matplotlib tight_layout()并没有考虑到graphicssuptitle

如果我添加一个字幕到我的matplotlib图中,它将被子图的标题覆盖。 有人知道如何轻松照顾这个吗? 我尝试了tight_layout()函数,但这只会让事情变得更糟。

例:

 import numpy as np import matplotlib.pyplot as plt f = np.random.random(100) g = np.random.random(100) fig = plt.figure() fig.suptitle('Long Suptitle', fontsize=24) plt.subplot(121) plt.plot(f) plt.title('Very Long Title 1', fontsize=20) plt.subplot(122) plt.plot(g) plt.title('Very Long Title 2', fontsize=20) plt.tight_layout() plt.show() 

您可以在tight_layout调用中调整子图几何,如下所示:

 fig.tight_layout(rect=[0, 0.03, 1, 0.95]) 

正如文档( https://matplotlib.org/users/tight_layout_guide.html )中所述:

tight_layout()只考虑tick标签,轴标签和标题。 因此,其他艺术家可能被剪辑,也可能重叠。

PS社区build议我发表我的评论作为答案。

您可以使用plt.subplots_adjust(top=0.85)手动调整间距:

 import numpy as np import matplotlib.pyplot as plt f = np.random.random(100) g = np.random.random(100) fig = plt.figure() fig.suptitle('Long Suptitle', fontsize=24) plt.subplot(121) plt.plot(f) plt.title('Very Long Title 1', fontsize=20) plt.subplot(122) plt.plot(g) plt.title('Very Long Title 2', fontsize=20) plt.subplots_adjust(top=0.85) plt.show() 

你可以很容易地改变你的代码的一件事是你正在使用的fontsize 。 但是,我会假设你不只是想这样做!

一些替代使用fig.subplots_adjust(top=0.85)

通常tight_layout()在把所有东西放在正确的位置上做的很好,所以它们不会重叠。 在这种情况下, tight_layout()没有帮助的原因是因为tight_layout()没有考虑到fig.suptitle()。 在GitHub上有一个关于这个的问题: https : //github.com/matplotlib/matplotlib/issues/829 [2014年因为需要一个完整的几何pipe理器而closures – 转移到https://github.com/matplotlib/matplotlib / issues / 1109 ]。

如果你读了这个线程,那么你的问题GridSpec的解决scheme。 关键是在调用tight_layout ,使用rect kwarg在图的顶部留出一些空间。 对于你的问题,代码变成:

使用GridSpec

 import numpy as np import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec f = np.random.random(100) g = np.random.random(100) fig = plt.figure(1) gs1 = gridspec.GridSpec(1, 2) ax_list = [fig.add_subplot(ss) for ss in gs1] ax_list[0].plot(f) ax_list[0].set_title('Very Long Title 1', fontsize=20) ax_list[1].plot(g) ax_list[1].set_title('Very Long Title 2', fontsize=20) fig.suptitle('Long Suptitle', fontsize=24) gs1.tight_layout(fig, rect=[0, 0.03, 1, 0.95]) plt.show() 

结果:

使用gridspec

也许GridSpec对你来说有点矫枉过正,否则你的真正的问题会涉及到更大的canvas或更多的复杂的更多的subplots。 一个简单的黑客就是使用annotate()并将坐标locking到'figure fraction'来模仿suptitle 。 但是,当您查看输出时,您可能需要进行一些更精细的调整。 请注意,这第二个解决scheme不使用tight_layout()

更简单的解决scheme (虽然可能需要进行微调)

 fig = plt.figure(2) ax1 = plt.subplot(121) ax1.plot(f) ax1.set_title('Very Long Title 1', fontsize=20) ax2 = plt.subplot(122) ax2.plot(g) ax2.set_title('Very Long Title 2', fontsize=20) # fig.suptitle('Long Suptitle', fontsize=24) # Instead, do a hack by annotating the first axes with the desired # string and set the positioning to 'figure fraction'. fig.get_axes()[0].annotate('Long Suptitle', (0.5, 0.95), xycoords='figure fraction', ha='center', fontsize=24 ) plt.show() 

结果:

简单

[使用Python 2.7.3(64位)和matplotlib 1.2.0]

另一个简单易用的解决scheme是使用suptitle调用中的y参数来调整图中suptitle文本的坐标(参见文档 ):

 import numpy as np import matplotlib.pyplot as plt f = np.random.random(100) g = np.random.random(100) fig = plt.figure() fig.suptitle('Long Suptitle', y=1.05, fontsize=24) plt.subplot(121) plt.plot(f) plt.title('Very Long Title 1', fontsize=20) plt.subplot(122) plt.plot(g) plt.title('Very Long Title 2', fontsize=20) plt.show() 

我一直在用matplotlib修剪方法,所以我现在只是通过bash调用ImageMagick的mogrify命令来做到这一点,这个方法效果很好,并且可以在graphics边缘获得所有额外的空白区域。 这要求您使用的是UNIX / Linux,正在使用bash shell,并安装了ImageMagick

只需在savefig()调用之后调用此savefig()

 def autocrop_img(filename): '''Call ImageMagick mogrify from bash to autocrop image''' import subprocess import os cwd, img_name = os.path.split(filename) bashcmd = 'mogrify -trim %s' % img_name process = subprocess.Popen(bashcmd.split(), stdout=subprocess.PIPE, cwd=cwd)