【问题标题】:How to remove gaps between *images* in matplotlib?如何消除 matplotlib 中 *images* 之间的间隙?
【发布时间】:2017-07-29 06:55:14
【问题描述】:

this question 的启发,我一直在尝试绘制没有间隙的图像。

在我的玩具示例中,我想将四张图片放在两行中。它们有不同的形状:不同的行数,相同的列数。尽管存在差异,但它们应该无间隙地放在一个图形中,如下图所示:

但是,当我尝试将它们组合在一起时,设置 plt.subplots_adjust(wspace=0, hspace=0) 并不能解决问题,因为图像具有不同的形状。

代码如下:

from numpy.random import rand
import matplotlib.pyplot as plt

test_data = [[rand(10,10), rand(10,10)],[rand(5,10), rand(5,10)]]
f, axarr = plt.subplots(2,2)
for i in range(2):
    for j in range(2):
        axarr[i, j].imshow(test_data[i][j])
plt.tight_layout()
plt.subplots_adjust(wspace=0, hspace=0)
plt.show()

我尝试过使用set_aspectequal,但没有运气。

有谁知道如何消除这些差距?

【问题讨论】:

  • 您要保留轴刺和刻度标签吗?生成的图像应该紧贴图形边界还是应该留出一些空间?这种差距会是任意的吗?
  • 不,我不想要轴刺和刻度标签,因为我正在显示图像。我会用.axis('off') 删除它们。理想情况下,生成的图像应该紧贴图形边界,但我不介意一个简单的解决方案是否还有一些空间。我不想要任何差距,所以差距不是任意的,它总是 0(如果我正确理解了你的问题)。图像大小可能会发生变化,但我们可以假设其中一个维度始终相同。

标签: python matplotlib imshow


【解决方案1】:

您可以在对plt.subplots 的调用中使用gridspec_kw 参数设置子图的height_ratios,并使用不同图像的高度来设置该比率。

从文档到plt.subplots()

gridspec_kw : 字典,可选

带有关键字的字典传递给用于创建放置子图的网格的 GridSpec 构造函数。

请注意,您的示例具有默认 matplotlib 图像大小的确切纵横比,因此在添加更多行或更改图像形状之前,您不会注意到出现任何间隙。

因此,要将其扩展为通用解决方案,您需要根据图像的形状设置图形大小。例如,让我们将您的示例扩展为 3 行 2 列。我们还将显式设置图形宽度为 8 英寸,并根据图像大小调整高度。

from numpy.random import rand
import matplotlib.pyplot as plt

test_data = [[rand(10,10), rand(10,10)],[rand(5,10), rand(5,10)],[rand(2,10), rand(2,10)]]
cmaps = [['viridis', 'binary'], ['plasma', 'coolwarm'], ['Greens', 'copper']]

heights = [a[0].shape[0] for a in test_data]
widths = [a.shape[1] for a in test_data[0]]

fig_width = 8.  # inches
fig_height = fig_width * sum(heights) / sum(widths)

f, axarr = plt.subplots(3,2, figsize=(fig_width, fig_height),
        gridspec_kw={'height_ratios':heights})

for i in range(3):
    for j in range(2):
        axarr[i, j].imshow(test_data[i][j], cmap=cmaps[i][j])
        axarr[i, j].axis('off')
plt.subplots_adjust(wspace=0, hspace=0, left=0, right=1, bottom=0, top=1)
plt.show()

【讨论】:

  • 非常优雅。谢谢
  • 我尝试使用plt.subplots(3,2, gridspec_kw={'height_ratios':(h1,h2,h3)}) 将解决方案推广到多行,这很有效,但随后列之间出现了间隙。关于如何处理的任何建议?
  • 您还需要设置figsize 来考虑整个数组的形状。查看我的编辑。
【解决方案2】:

您可以将所有图像合并到一个数组中,然后使用imshow 进行绘图。
为了确保图像周围没有多余的间距,我们需要计算纵横比并相应地设置图形大小。 (为了表明我将下部图像的像素数更改为 4)。

from numpy.random import rand
import matplotlib.pyplot as plt
import numpy as np

test_data = [[rand(10,10), rand(10,10)],[rand(4,10), rand(4,10)]]
a = np.c_[np.array(test_data[0][0]),np.array(test_data[0][1]) ]
b = np.c_[np.array(test_data[1][0]),np.array(test_data[1][1]) ]
c = np.r_[a,b]

dpi=100
width = 5 #inch
height = width*c.shape[0]/float(c.shape[1])
fig, ax = plt.subplots(figsize=(width,height ), dpi=dpi)
ax.imshow(c)
ax.axis("off")
plt.subplots_adjust(0,0,1,1)
plt.savefig(__file__+".png")
plt.show()

【讨论】:

  • 谢谢!我无法告诉您我查看了多少 Stack Overflow 答案,其中提供的解决方案没有摆脱矩形图的所有填充。在plt.subplots 中设置figsize=(width, height) 是关键。
猜你喜欢
  • 2013-12-25
  • 2016-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-10
  • 2010-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多