为什么如果我使用'紧密的'对于使用fig.legend方法的bbox_inches?

时间:2018-01-06 14:53:50

标签: matplotlib legend

我正在尝试制作一个图像,我将图例放在轴外。但我发现如果我在bbox_inches='tight'方法中使用plt.savefig(),则生成的图片不包含图例。最简单的工作示例如下:

import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl

x = np.arange(-5, 5, 0.1)
y1 = np.sin(x)
y2 = np.cos(x)


fig, ax1= plt.subplots(ncols=1, nrows=1, figsize=(10, 6))

ax1.plot(x, y1, label='sin(x)')
ax1.plot(x, y2, label='cos(x)')

handles, labels = ax1.get_legend_handles_labels()

plt.figlegend(handles, labels, loc='upper left', ncol=2, frameon=False,
              bbox_to_anchor=(0.11, 0.95))

plt.savefig('test.jpg', bbox_inches='tight')

生成的test.jpg如下所示 Image without legend

如果我在bbox_inches='tight'方法中移除savefig()。(如下所示),图例会出现在制作的图像中,但图像的四边有两个很大的空白区域。

enter image description here

是否有一种很好的方法可以保留图像的紧密布局并将图例保留在生成的图像中?

编辑1

按照this post中的说明,我还尝试在bbox_extra_artists方法中使用savefig()参数,类似这样

legend = plt.figlegend(handles, labels, loc='lower left', ncol=2, frameon=True,
              bbox_to_anchor=(0.12, 0.88))
plt.savefig('test.jpg', bbox_extra_artists=(legend,), bbox_inches='tight')

正如@Diziet Asahi和@mportanceOfBeingErnest指出的那样,如果我们使用ax.legend()方法,一切正常。以下代码有效,

legend = ax1.legend(handles, labels, ncol=2, frameon=False,
                    loc='lower left', bbox_to_anchor=(-0.01, 1.2))
plt.savefig('test.jpg', bbox_inches='tight')

EDIT2

According to the Matplotlib developer,当我们使用严格布局时,似乎没有考虑fig.legend方法生成的图例的错误。

2 个答案:

答案 0 :(得分:2)

您可以使用图形轴之一的.legend()方法创建图例。为了在图坐标中指定图例坐标,就像使用figlegend一样,您可以使用bbox_transform参数。

ax1.legend(handles, labels, loc='upper left', ncol=2, frameon=False,
              bbox_to_anchor=(0.11, 0.95), bbox_transform=fig.transFigure)

答案 1 :(得分:1)

我无法准确说明它为什么会发生(对我来说似乎是一个错误),但问题在于您使用顶级plt.figlegend()函数。如果使用Figure.legend(),问题仍然存在,但如果将其替换为Axes.legend()则会消失:

legend = ax1.legend(handles, labels, loc='lower left', ncol=2, frameon=False,
              bbox_to_anchor=(0,1.2))
fig.savefig('test.jpg', bbox_extra_artists=[legend], bbox_inches='tight')

enter image description here