Matplotlib缩放轴长度以达到相等的效果。

9

我有两个子图:

plt.subplot(1, 2, 1)
plt.plot(x, y)
plt.subplot(1, 2, 2)
plt.plot(u, v)
< p > uv的范围均为[0,1],而xy的范围是随机的,且xy不同。我希望将这两个子图都变成正方形,因此x轴的长度应等于y轴的长度。对于第二个子图,可以通过另一个SO问题轻松解决:

plt.subplot(1, 2, 1)
plt.plot(x, y)
plt.subplot(1, 2, 2)
plt.plot(u, v)
plt.axis('scaled')

然而,这种方法对于第一个子图不起作用,因为它会将y轴缩小到非常小的值,因为该值在一个小范围内,而x轴基本上在[0,1]的范围内,因此它与第二个子图具有相同的比例。

我该如何将第一个子图的y轴缩放以使其长度等于其他轴的长度?


1
“x轴的长度应该等于y轴的长度” 您是指数据单位、屏幕单位还是两者都是? - Stop harming Monica
2
@Goyo 屏幕单元 - Gábor Erdős
1
我不理解这个问题。你能在例子中使用实际数据并解释一下使用这些数据得到的图表有什么问题吗? - ImportanceOfBeingErnest
3个回答

12
你希望你的子图是正方形的。函数plt.axis接受'square'作为参数,并且它确实是这个意思:它会使当前轴在像素和数据单位上都成为正方形。
x = np.arange(2)
y = x / 3
u = v = [0, 1]

plt.subplot(121)
plt.plot(x, y)
plt.axis('square')

plt.subplot(122)
plt.plot(u, v)
plt.axis('square')

在此输入图片描述

不幸的是,这将使Y轴限制范围远远超出Y数据范围,这不是您想要的。您需要的是子图的宽高比为数据范围比例的倒数。据我所知,没有任何方便的函数或方法可以实现此功能,但您可以编写自己的函数。

def make_square_axes(ax):
    """Make an axes square in screen units.

    Should be called after plotting.
    """
    ax.set_aspect(1 / ax.get_data_ratio())

plt.subplot(121)
plt.plot(x, y)
make_square_axes(plt.gca())

plt.subplot(122)
plt.plot(u, v)
make_square_axes(plt.gca())

输入图像描述


3

@停止伤害Monica是一个很好的答案。我还发现了一种新的方法来实现这个目标(使用ax.set_box_aspect)。

盒子纵横比是物理单位中轴高度和轴宽度之间的比率,独立于数据极限

我认为这正是你想要的。

有关详细信息,请参见演示API参考

示例(代码在@停止伤害Monica中)

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(2)
y = x / 3
u = v = [0, 1]

plt.subplot(121)
plt.plot(x, y)
plt.gca().set_box_aspect(1)

plt.subplot(122)
plt.plot(u, v)
plt.axis('square')

plt.show()

enter image description here

注意

ax.set_box_aspect是一个新的方法。matplotlib版本应该至少为3.3.0


2

由于您需要等轴线,因此应该设置plt.axis('equal')而不是'scaled'。实际上,即使对于第二种情况,也应该使用'equal'关键字来给出一个正方形的图形。

x = np.linspace(1, 0.1, 10)
y = np.linspace(1, 1, 10)
fig, ax = plt.subplots(figsize=(5, 5))
ax.plot(x, y, '.')
ax.axis('equal')
plt.show()

正方形图,等比例缩放

请注意,将figsize设置为(length, length)会得到一个实际的正方形,否则默认的图形大小会被占用。


在这种情况下,尝试将figsize设置为(2, 2)或(n, n),或者参见此处,如果您正在尝试对子图进行此操作。无论哪种方式,也许您应该更新问题以指定此要求。 - krm
我认为问题很清楚,我指出了子图,并且也指出每个轴应该具有相同的长度。在这个答案中,如果有两个子图,则Y轴的长度等于2*X轴的长度。 - Gábor Erdős
你似乎删除了指定“ylim”在此之后仍然有效的注释。无论如何,如果您想要排列为两行的2个子图,figsize =(2,4)是否有帮助?或者如果您想要列,则使用figsize =(4,2)? - krm
设置figsize不会使轴长度相等。使用(5,10)仍然存在一些绘图之间的间距,这使得长度不均匀。 - Gábor Erdős

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