如何消除 matplotlib 中 *images* 之间的间隙?
How to remove gaps between *images* in matplotlib?
受到 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_aspect
和 equal
,但没有成功。
有谁知道如何消除这些差距?
您可以在对 plt.subplots
的调用中使用 gridspec_kw
参数设置子图的 height_ratios
,并使用不同图像的高度来设置该比例。
从文档到 plt.subplots()
:
gridspec_kw : dict, optional
Dict with keywords passed to the GridSpec constructor used to create the grid the subplots are placed on.
请注意,您的示例具有默认 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()
您可以将所有图像组合成一个数组,然后用 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()
受到 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_aspect
和 equal
,但没有成功。
有谁知道如何消除这些差距?
您可以在对 plt.subplots
的调用中使用 gridspec_kw
参数设置子图的 height_ratios
,并使用不同图像的高度来设置该比例。
从文档到 plt.subplots()
:
gridspec_kw : dict, optional
Dict with keywords passed to the GridSpec constructor used to create the grid the subplots are placed on.
请注意,您的示例具有默认 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()
您可以将所有图像组合成一个数组,然后用 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()