如何消除matplotlib中子图之间的间隙?


116

下面的代码在子图之间产生间隙。如何消除子图之间的间隙并使图像紧密网格?

在此处输入图片说明

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

2
发布链接,可以对其进行编辑。 None没有按照您的想法做,这意味着“使用默认设置”。
tacaswell

我尝试添加数字而不是“无”,但这并没有解决问题。
user3006135

4
plt.subplots_adjust(wspace=0, hspace=0)会解决您的问题,如果不是因为您使用'equal'方面。有关详细信息,请参见我的答案。
2016年

Answers:


100

您可以使用gridspec来控制轴之间的间距。这里有更多信息

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

轴非常靠近


35
它不限于GridSpec,如果您在创作时抓住了身影,您还可以使用以下方法设置距离:fig.subplots_adjust(hspace=, wspace=)
罗格·卡西斯

3
for循环中的最后一行是什么意思?
CiprianTomoiagă18年

这是一个非常好的技巧,但没有使用subplots这个答案使工作得以完成而没有牺牲subplots
wizclown

有一种方法,以除去水平间距只有轴的第一和第二行之间?
斯特凡诺

136

问题是使用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)

结果如下:


3
谢谢!您的答案很简单,效果很好。plt.subplots_adjust(wspace=0, hspace=0)
MohamedEzz

35

在不完全采用gridspec的情况下,还可以通过将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()

导致:

。


4

你试过了plt.tight_layout()吗?

plt.tight_layout() 在此处输入图片说明 没有它: 在此处输入图片说明

或者:类似这样的东西(使用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) 在此处输入图片说明


我尝试了紧凑的布局,但并没有消除空白,这就是我想要的。gridspec解决方案有效。感谢您的建议。
user3006135

与其他建议一起使用时,效果很好。ighted_layout()有助于删除无用的情节上方和侧面的空白。
DChaps

0

对于最新的matplotlib版本,您可能需要尝试Constrained Layoutplt.subplot()但是,这不起作用,因此您需要使用plt.subplots()

fig, axs = plt.subplots(4, 4, constrained_layout=True)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.