Matplotlib自动传说外图

ede*_*esz 17 python plot matplotlib legend legend-properties

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

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

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()
Run Code Online (Sandbox Code Playgroud)

它基于以下示例:http: //matplotlib.org/users/legend_guide.html#plotting-guide-legend

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

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

  1. 传说下面的情节
  2. 传说上面的情节
  3. 情节右侧的传说

如果没有,是否有可能在Python中对这些数字做出好的猜测?

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

Mor*_*itz 27

编辑:

我强烈建议使用来自ImportanceOfBeingErnest的答案: 如何将图例放出情节

这个更容易理解:

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()
Run Code Online (Sandbox Code Playgroud)

现在使用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
Run Code Online (Sandbox Code Playgroud)


小智 8

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

matplotlib 坐标系

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

lgd = plt.legend(bbox_to_anchor=(1.01, 1), loc='upper left')
Run Code Online (Sandbox Code Playgroud)

然而,这不会相对于图形重新定位轴,这可能会将图例定位在图形画布之外。为了自动重新定位图形画布以与轴和图例对齐,我使用了以下算法。

首先,在画布上绘制图例以为其分配实际像素坐标:

plt.gcf().canvas.draw()
Run Code Online (Sandbox Code Playgroud)

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

invFigure = plt.gcf().transFigure.inverted()
Run Code Online (Sandbox Code Playgroud)

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

lgd_pos = lgd.get_window_extent()
lgd_coord = invFigure.transform(lgd_pos)
lgd_xmax = lgd_coord[1, 0]
Run Code Online (Sandbox Code Playgroud)

对 Axes 执行相同操作:

ax_pos = plt.gca().get_window_extent()
ax_coord = invFigure.transform(ax_pos)
ax_xmax = ax_coord[1, 0]
Run Code Online (Sandbox Code Playgroud)

最后,使用 tiny_layout 调整图形画布,调整必须移动的轴的比例,以便为图例留出适合画布的空间:

shift = 1 - (lgd_xmax - ax_xmax)
plt.gcf().tight_layout(rect=(0, 0, shift, 1))
Run Code Online (Sandbox Code Playgroud)

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