在matplotlib中创建正方形子图(等高等宽)

30 投票
2 回答
84381 浏览
提问于 2025-04-16 01:00

当我运行这段代码时

from pylab import *

figure()
ax1 = subplot(121)
plot([1, 2, 3], [1, 2, 3])
subplot(122, sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
draw()
show()

我得到的两个子图在X轴上看起来很“挤”。我该怎么做才能让这两个子图的Y轴高度和X轴宽度相等呢?

我在Ubuntu 10.04上使用的是matplotlib版本0.99.1.2。

更新 2010-07-08: 让我们看看一些不起作用的尝试。

我在网上查了一整天,觉得这可能和自动缩放有关。所以我尝试调整了一下这个设置。

from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
subplot(122, sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
draw()
show()

但是matplotlib坚持要自动缩放。

from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
subplot(122, sharex=ax1, sharey=ax1, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
draw()
show()

在这个尝试中,数据完全消失了。天哪,matplotlib这是怎么回事?真是让人无语。

好吧,也许我们可以调整一下长宽比?

from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False)
plot([1, 2, 3], [1, 2, 3])
axes().set_aspect('equal')
subplot(122, sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
draw()
show()

结果这个尝试让第一个子图完全消失了。太搞笑了!谁想出的这个主意?

说真的,这难道真的应该这么难吗?

2 个回答

2

试试这个:

from pylab import *

figure()
ax1 = subplot(121, autoscale_on=False, aspect='equal', xlim=[1,3], ylim=[1,3])
plot([1, 2, 3], [1, 2, 3])
##axes().set_aspect('equal')
ax2 = subplot(122, autoscale_on=False, aspect='equal', xlim=[1,3], ylim=[1,3])
plot([1, 2, 3], [1, 2, 3])
draw()
show()

我把 axes() 这一行注释掉了,因为那样会在一个随意的位置创建一个新的 axes,而不是一个已经计算好位置的 subplot

调用 subplot 实际上是创建了一个 Axes 实例,这意味着它可以使用和 Axes 一样的属性。

希望这对你有帮助 :)

26

你在设置图表的比例时遇到的问题是因为你使用了共享坐标轴(sharex 和 sharey)。

一个简单的解决办法就是不使用共享坐标轴。比如,你可以这样做:

from pylab import *

figure()
subplot(121, aspect='equal')
plot([1, 2, 3], [1, 2, 3])
subplot(122, aspect='equal')
plot([1, 2, 3], [1, 2, 3])
show()

不过,更好的解决办法是改变“可调节”的参数... 你想要设置为 adjustable='box',但是当你使用共享坐标轴时,它必须设置为 adjustable='datalim'(如果你把它改回 'box',就会出错)。

不过,还有第三种选择可以处理这种情况:adjustable="box-forced"

比如:

from pylab import *

figure()
ax1 = subplot(121, aspect='equal', adjustable='box-forced')
plot([1, 2, 3], [1, 2, 3])
subplot(122, aspect='equal', adjustable='box-forced', sharex=ax1, sharey=ax1)
plot([1, 2, 3], [1, 2, 3])
show()

或者用更现代的写法(注意:这个部分在2010年是无法使用的):

import matplotlib.pyplot as plt

fig, axes = plt.subplots(ncols=2, sharex=True, sharey=True)
for ax in axes:
    ax.plot([1, 2, 3], [1, 2, 3])
    ax.set(adjustable='box-forced', aspect='equal')

plt.show()

无论哪种方式,你最终会得到类似这样的效果:

在这里输入图片描述

撰写回答