在matplotlib中创建正方形子图(等高等宽)
当我运行这段代码时
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()
无论哪种方式,你最终会得到类似这样的效果: