如何在 matplotlib 中消除子情节之间的间隙

下面的代码在子图之间产生间隙。如何消除子情节之间的差距,使图像一个紧密的网格?

enter image description here

import matplotlib.pyplot as plt


for i in range(16):
i = i + 1
ax1 = plt.subplot(4, 4, i)
plt.axis('on')
ax1.set_xticklabels([])
ax1.set_yticklabels([])
ax1.set_aspect('equal')
plt.subplots_adjust(wspace=None, hspace=None)
plt.show()
211314 次浏览

你试过 plt.tight_layout()吗?

plt.tight_layout() enter image description here 没有它: enter image description here

或者: 类似的东西(使用 add_axes)

left=[0.1,0.3,0.5,0.7]
width=[0.2,0.2, 0.2, 0.2]
rectLS=[]
for x in left:
for y in left:
rectLS.append([x, y, 0.2, 0.2])
axLS=[]
fig=plt.figure()
axLS.append(fig.add_axes(rectLS[0]))
for i in [1,2,3]:
axLS.append(fig.add_axes(rectLS[i],sharey=axLS[-1]))
axLS.append(fig.add_axes(rectLS[4]))
for i in [1,2,3]:
axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))
axLS.append(fig.add_axes(rectLS[8]))
for i in [5,6,7]:
axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))
axLS.append(fig.add_axes(rectLS[12]))
for i in [9,10,11]:
axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))

如果不需要共享轴,那么可以简单地使用 axLS=map(fig.add_axes, rectLS) enter image description here

你可以使用 网格规格来控制轴之间的间距。这里有更多的 资料

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec


plt.figure(figsize = (4,4))
gs1 = gridspec.GridSpec(4, 4)
gs1.update(wspace=0.025, hspace=0.05) # set the spacing between axes.


for i in range(16):
# i = i + 1 # grid spec indexes from 0
ax1 = plt.subplot(gs1[i])
plt.axis('on')
ax1.set_xticklabels([])
ax1.set_yticklabels([])
ax1.set_aspect('equal')


plt.show()

axes very close together

问题在于 aspect='equal'的使用,它防止子情节拉伸到任意长宽比,并填满所有的空白空间。

通常情况下,这会奏效:

import matplotlib.pyplot as plt


ax = [plt.subplot(2,2,i+1) for i in range(4)]


for a in ax:
a.set_xticklabels([])
a.set_yticklabels([])


plt.subplots_adjust(wspace=0, hspace=0)

结果是:

但是,对于 aspect='equal',如下面的代码所示:

import matplotlib.pyplot as plt


ax = [plt.subplot(2,2,i+1) for i in range(4)]


for a in ax:
a.set_xticklabels([])
a.set_yticklabels([])
a.set_aspect('equal')


plt.subplots_adjust(wspace=0, hspace=0)

这就是我们得到的:

第二种情况的不同之处在于,您强制 x 轴和 y 轴具有相同数量的单位/像素。由于坐标轴在默认情况下从0到1(也就是说,在绘制任何东西之前) ,因此使用 aspect='equal'会迫使每个坐标轴成为一个正方形。由于该图不是一个正方形,pyplot 在轴之间水平增加了额外的间距。

为了解决这个问题,您可以设置您的数字有正确的纵横比。我们将在这里使用面向对象的 pyplot 接口,我认为它通常比较优越:

import matplotlib.pyplot as plt


fig = plt.figure(figsize=(8,8)) # Notice the equal aspect ratio
ax = [fig.add_subplot(2,2,i+1) for i in range(4)]


for a in ax:
a.set_xticklabels([])
a.set_yticklabels([])
a.set_aspect('equal')


fig.subplots_adjust(wspace=0, hspace=0)

结果是这样的:

在不完全使用 网格规格的情况下,也可以通过将 WspaceHspace设置为零来消除以下差距:

import matplotlib.pyplot as plt


plt.clf()
f, axarr = plt.subplots(4, 4, gridspec_kw = {'wspace':0, 'hspace':0})


for i, ax in enumerate(f.axes):
ax.grid('on', linestyle='--')
ax.set_xticklabels([])
ax.set_yticklabels([])


plt.show()
plt.close()

结果:

.

对于最近的 matplotlib 版本,您可能想尝试 受限布局。但是,这对 plt.subplot()不起作用(或者至少不起作用) ,因此您需要使用 plt.subplots():

fig, axs = plt.subplots(4, 4, constrained_layout=True)

另一种方法是使用来自 plt.subplots_adjust()pad关键字,它也接受负值:

import matplotlib.pyplot as plt


ax = [plt.subplot(2,2,i+1) for i in range(4)]


for a in ax:
a.set_xticklabels([])
a.set_yticklabels([])


plt.subplots_adjust(pad=-5.0)

另外,要去除所有子情节(即画布)外边缘的白色,始终使用 plt.savefig(fname, bbox_inches="tight")保存。