Matplotlib - 固定纵横比的子图

32
我有一个绘制多个子图的问题。我想将子图的物理纵横比设置为固定值。 在我的示例中,我在横向A4图上有12个子图(4行3列)。所有子图都很好地放置在整个图上,并且对于所有子图,高度几乎等于宽度。
但是,如果我将我的图的布局更改为纵向,则子图会在垂直方向上被拉伸。 这正是不应该发生的。我希望与横向图上的子图具有相同的高度和宽度。是否有可能使子图的纵横比保持不变?
提前感谢, Peter 编辑: 我已经找到了一种解决方法。但这仅适用于非对数轴...
aspectratio=1.0
ratio_default=(ax.get_xlim()[1]-ax.get_xlim()[0])/(ax.get_ylim()[1]-ax.get_ylim()[0])
ax.set_aspect(ratio_default*aspectratio)
3个回答

22

实际上,您想要的很简单... 您只需要确保在坐标轴上将adjustable设置为'box',并且您对坐标轴有一个固定的纵横比(除了'auto')。

您可以在创建子图时使用adjustable关键字参数来实现此目的。或者,您可以在创建后通过调用ax.set_adjustable('box')ax.set_aspect(aspect, adjustable='box')来完成。其中aspect是'equal'或一个数字。

现在,无论如何调整图形大小,子图都将保持相同的纵横比。

例如:

import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(2,1,1, adjustable='box', aspect=0.3)
ax2 = fig.add_subplot(2,1,2)

ax1.plot(range(10))
ax2.plot(range(10))

plt.show()
现在,比较一下顶部子图的调整大小响应和底部子图的响应:
初始图: alt text 调整为竖向布局: alt text 调整为横向布局: alt text

3
你好!感谢你的回复。不幸的是,这只设置了子图轴的纵横比。由于我的轴有许多不同的范围,我必须为每个子图单独设置这个纵横比。所以我想做的是将我的子图的高度和宽度(而不仅仅是轴)设置为特定的纵横比。 - Peter Waltons

6
你的解决方案对我有效。绘制数据后,我调用以下函数:
def fixed_aspect_ratio(ratio):
    '''
    Set a fixed aspect ratio on matplotlib plots 
    regardless of axis units
    '''
    xvals,yvals = gca().axes.get_xlim(),gca().axes.get_ylim()

    xrange = xvals[1]-xvals[0]
    yrange = yvals[1]-yvals[0]
    gca().set_aspect(ratio*(xrange/yrange), adjustable='box')

这对我很有效。我修改了函数以接受ax参数,从而可以将其应用于子图。我还用ax替换了gca().axesgca() - Steve

3

针对原问题编辑中有关解决方法在对数图上无效的评论,您需要进行如下适应:

def fixed_aspect_ratio_loglog(ratio):
    '''
    Set a fixed aspect ratio on matplotlib loglog plots 
    regardless of axis units
    '''
    xvals,yvals = gca().axes.get_xlim(),gca().axes.get_ylim()

    xrange = log(xvals[1])-log(xvals[0])
    yrange = log(yvals[1])-log(yvals[0])
    gca().set_aspect(ratio*(xrange/yrange), adjustable='box')

对于半对数图的调整现在应该很明显了。


gca() 是谁? - Victor Eijkhout
@VictorEijkhout 获取当前轴 - Neinstein

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接