2017-03-08 112 views
2

this question的启发,我一直试图让图像没有空白的绘制。如何清除matplotlib中* images *之间的间隙?

在我的玩具例子中,我有四个图像,我想放在两排。他们有不同的形状:不同的行数,列数相同。尽管有分歧,他们应该适合在无间隙的一个单一的数字,如如下图所示:

it fits

当我试图让他们在一起,不过,设置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玩耍,但没有运气。

nofits

有谁知道如何获得这些差距了吗?

+0

你想保持轴刺和ticklabels?产生的图像是否应该紧贴图形边界,还是应该留下一些空间?这个差距是任意的吗? – ImportanceOfBeingErnest

+0

不,我不想要显示图像的轴棘和剔标签。我会用'.axis('off')'去除它们。由此产生的图像理想情况下应该与图形边界保持一致,但我不介意简单的解决方案是否留有一些空间。我不需要任何差距,所以差距不是任意的,它总是0(如果我正确理解你的问题)。图像大小可能会改变,但我们可以假设其中一个维度总是相同的。 – dangom

回答

4

您可以在调用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() 

enter image description here

+0

非常优雅。谢谢 – dangom

+0

我试图通过使用'plt.subplots(3,2,gridspec_kw = {'height_ratios':(h1,h2,h3)})''将其推广到多行,悄悄进入。有关如何处理这个问题的任何建议? – dangom

+1

您还需要设置'figsize'来说明总阵列的形状。看我的编辑。 – tom

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() 

enter image description here

相关问题