Matplotlib自动传说外图

时间:2015-05-23 14:22:58

标签: python matplotlib plot legend legend-properties

我正在尝试在Python的matplotlib图中使用关键字bbox_to_anchor()

这是我制作的一个非常基本的情节:

import matplotlib.pyplot as plt
x = [1,2,3]
plt.subplot(211)
plt.plot(x, label="test1")
plt.plot([3,2,1], label="test2")
plt.legend(bbox_to_anchor=(0, -0.15, 1, 0), loc=2, ncol=2, mode="expand", borderaxespad=0)
plt.show()

这是基于这里的例子: http://matplotlib.org/users/legend_guide.html#plotting-guide-legend

我正在尝试使用bbox_to_anchor()自动将图例放在图表之外。在此示例中,bbox_to_anchor()列出了4个参数。

在此特定示例(上图)中,图例位于图表下方,因此每次更改图表时需要手动输入数字-0.15(字体大小,轴标题删除等)。 是否可以针对以下情况自动计算这4个数字?

  1. 传说下面的情节
  2. 上面的图例
  3. 情节右侧的传奇
  4. 如果没有,是否有可能在Python中对这些数字做出正确的猜测?

    此外,在上面的示例代码中,我将bbox_to_anchor()中的最后2个数字设置为1和0,因为我不明白它们是什么或它们是如何工作的。 bbox_to_anchor()中的最后两个数字是什么意思?

2 个答案:

答案 0 :(得分:22)

编辑:

我强烈建议使用来自ImportanceOfBeingErnest的答案: How to put the legend out of the plot

这个更容易理解:

import matplotlib.pyplot as plt
x = [1,2,3]
plt.subplot(211)
plt.plot(x, label="test1")
plt.plot([3,2,1], label="test2")
plt.legend(bbox_to_anchor=(0, 1), loc='upper left', ncol=1)
plt.show()

现在使用to坐标(x,y)。对于loc,您可以使用:

valid locations are:
right
center left
upper right
lower right
best
center
lower left
center right
upper left
upper center
lower center

答案 1 :(得分:4)

bbox_to_anchor的参数位于Axes Coordinates中。 matplotlib使用不同的坐标系来简化屏幕上对象的放置。处理定位图例时,要处理的关键坐标系是Axes坐标,图坐标和Display坐标(以像素为单位),如下所示:

matplotlib coordinate systems

如前所述,bbox_to_anchor位于Axes坐标中,并不需要矩形的所有4个元组参数。你可以简单地在Axes坐标中给它一个包含(xpos,ypos)的两参数元组。在这种情况下,loc参数将定义图例的锚点。因此,要将图例固定在轴的右外侧并与顶边对齐,您将发出以下内容:

lgd = plt.legend(bbox_to_anchor=(1.01, 1), loc='upper left')

然而,这并没有相对于图重新定位Axes,这可能会使图例偏离图画布。要自动重新定位“图”画布以与“轴”和图例对齐,我使用了以下算法。

首先,在画布上绘制图例,为其指定实像素坐标:

plt.gcf().canvas.draw()

然后定义转换从像素坐标到图坐标:

invFigure = plt.gcf().transFigure.inverted()

接下来,以像素为单位获取图例范围并转换为图形坐标。拉出x方向的最远范围,因为这是我们需要调整的画布方向:

lgd_pos = lgd.get_window_extent()
lgd_coord = invFigure.transform(lgd_pos)
lgd_xmax = lgd_coord[1, 0]

为Axes做同样的事情:

ax_pos = plt.gca().get_window_extent()
ax_coord = invFigure.transform(ax_pos)
ax_xmax = ax_coord[1, 0]

最后,使用tight_layout调整图形画布,以获得必须移动的轴的比例,以允许图例适合画布的空间:

shift = 1 - (lgd_xmax - ax_xmax)
plt.gcf().tight_layout(rect=(0, 0, shift, 1))

请注意,tight_layout的rect参数位于图形坐标中,并定义包含Axes的tight_layout边界的矩形的左下角和右上角,其中不包括图例。所以一个简单的tight_layout调用相当于设置(0,0,1,1)的矩形边界。