使用matplotlib的imshow和scatter如何获得相同的子图大小

44

我正在尝试在同一张图中绘制一个图像(使用 matplotlib.imshow )和散点图。尝试这样做时,图像似乎比散点图小。下面是一个简单的示例代码:

import matplotlib.pyplot as plt
import numpy as np

image = np.random.randint(100,200,(200,200))
x = np.arange(0,10,0.1)
y = np.sin(x)

fig, (ax1, ax2) = plt.subplots(1,2)
ax1.imshow(image)
ax2.scatter(x,y)

plt.show()

这将得到以下图形:

enter image description here

我该如何使这两个子图具有相同的高度?(我想还包括宽度)

我尝试使用gridspec,如此回答所示:

fig=plt.figure()
gs=GridSpec(1,2)

ax1=fig.add_subplot(gs[0,0])
ax2=fig.add_subplot(gs[0,1])
ax1.imshow(image)
ax2.scatter(x,y)

但是这样会得到相同的结果。我也尝试使用以下方法手动调整子图的大小:

fig = plt.figure()
ax1 = plt.axes([0.05,0.05,0.45,0.9])
ax2 = plt.axes([0.55,0.19,0.45,0.62])

ax1.imshow(image)
ax2.scatter(x,y)

通过试错我可以将两个子图调整到正确的大小,但是如果更改整个图形的大小,则子图的大小将不再相同。

有没有一种方法可以使imshowscatter在图中呈现相同的大小而不必手动更改坐标轴大小?

我正在使用Python 2.7和matplotlib 2.0.0。

4个回答

61

你希望达到的结果并不是非常清楚。

  1. 你可以在图像上使用自动方面。

    ax.imshow(z, aspect="auto")
    

    在此输入图片描述

  2. 或者,您可以根据轴限制设置线图的纵横比,使其与图像大小相同(如果图像的 x 和 y 大小相等)。

  3. asp = np.diff(ax2.get_xlim())[0] / np.diff(ax2.get_ylim())[0]
    ax2.set_aspect(asp)
    

    输入图像描述 完整代码:

    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.linspace(0,10,20)
    y = np.sin(x)
    z = np.random.rand(100,100)
    
    fig, (ax, ax2) = plt.subplots(ncols=2)
    
    ax.imshow(z)
    ax2.plot(x,y, marker=".")
    
    asp = np.diff(ax2.get_xlim())[0] / np.diff(ax2.get_ylim())[0]
    ax2.set_aspect(asp)
    
    plt.show()
    
    如果图像的限制不相等(不是正方形),仍需要根据图像的长宽比进行除法操作:
    asp = np.diff(ax2.get_xlim())[0] / np.diff(ax2.get_ylim())[0]
    asp /= np.abs(np.diff(ax1.get_xlim())[0] / np.diff(ax1.get_ylim())[0])
    ax2.set_aspect(asp)
    
  4. 更复杂的解决方案:

    • 这个答案 介绍如何使用subplot参数实现特定的纵横比例。

    • 如果你想要使用mpl_toolkits并且认真钻研,这个答案是一个不错的参考。


期望的结果很简单,就是两个子图的大小完全相同,并且在调整图形大小时保持不变。无论如何,aspect='auto'解决了问题,谢谢。 - DavidG

4
我遇到了同样的问题并在stackoverflow上提出了一个非常类似的问题。 @ImportanceOfBeingErnest 提出的解决方案对我来说非常有效,但是为了完整起见,在我的问题被标记为与此重复之前,我想提及一个非常简单的解决方法(由@Yilun Zhang 提供):

问题是绘图区域的高度太大,这导致图像中出现空白的地方。

如果您将代码更改为:

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))

然后您将获得所需的结果:

所需结果


7
需要翻译的内容:The question to ask is, how did you figure out the (14, 6) was the correct size for the two plots to have the same height?你需要问的问题是,你是如何确定(14,6)是两个图形具有相同高度的正确尺寸的? - frankliuao
这个解决方案在左侧图像有色条的情况下不起作用。 - AlanWik

4

对于那些在两个图之间共享 y 轴的情况,将 constrained_layout 设置为 True 可能会有所帮助。


这对我很有效!我正在创建一个破碎的y轴(matplotlib.org示例),并且希望大小保持不变。 - das Keks

3

我使用的代码如下:

fig, axis_array = plt.subplots(1, 2, figsize=(chosen_value, 1.05 * chosen_value / 2),
                               subplot_kw={'aspect': 1})

我明确选择在我的图中有2个子图,而且这个图的高度将是chosen_value,每个子图的宽度将大约是该高度的一半,并且子图将具有1:1的纵横比(即它们都是正方形)。图形大小是一个特定的比率,它强制实现间距。


3
你的图表将看起来像这样:https://i.stack.imgur.com/fsGB2.png。我认为这不是OP想要的。 - ImportanceOfBeingErnest

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