如何在图形坐标中指定 matplotlib 中的图例位置

我知道 bbox _ to _ 壁虎关键字和这个线程,它非常有帮助地建议如何手动放置图例:

如何把传说从情节中抹去

然而,我希望在图中使用我的 x 轴和 y 轴的坐标来指定图例位置(在图中) ,因为我可能需要将图形移动到一个具有不同轴环境的大图中,而且我不想每次这样做时都要手动处理这些坐标。这可能吗?

编辑: 这里有一个小例子:

import numpy as n
f, axarr = plt.subplots(2,sharex=True)
axarr[1].set_ylim([0.611,0.675])
axarr[0].set_ylim([0.792,0.856])
axarr[0].plot([0, 0.04, 0.08],n.array([ 0.83333333,  0.82250521,0.81109048]), label='test1')
axarr[0].errorbar([0, 0.04, 0.08],n.array([ 0.8,  0.83,   0.82]),n.array([0.1,0.1,0.01]), label='test2')
axarr[1].plot([0, 0.04, 0.08],n.array([ 0.66666667,  0.64888304,  0.63042428]))
axarr[1].errorbar([0, 0.04, 0.08],n.array([ 0.67,  0.64,  0.62]),n.array([ 0.01,  0.05,  0.1]))
axarr[0].legend(bbox_to_anchor=(0.04, 0.82, 1., .102),labelspacing=0.1,       handlelength=0.1, handletextpad=0.1,frameon=False, ncol=4, columnspacing=0.7)

enter image description here

我认为让我困惑的是图例并不是从0.82开始的,而且对于我的更大的图(有5个这种类型的子图) ,我需要使用图例坐标 bbox _ to _ Anchor= (0.04,1.15,1)。为了使图例显示在坐标(0.02,0.83)上。但也许我还做错了什么?

275468 次浏览

可以使用 loc 参数更改图例的位置。 Https://matplotlib.org/stable/api/_as_gen/matplotlib.axes

import matplotlib.pyplot as plt


plt.subplot(211)
plt.plot([1,2,3], label="test1")
plt.plot([3,2,1], label="test2")
# Place a legend above this subplot, expanding itself to
# fully use the given bounding box.
plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,
ncol=2, mode="expand", borderaxespad=0.)


plt.subplot(223)
plt.plot([1,2,3], label="test1")
plt.plot([3,2,1], label="test2")
# Place a legend to the right of this smaller subplot.
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)


plt.show()

loc参数指定图例放置在边框的哪个角落。loc的默认值是 loc="best",当使用 bbox_to_anchor参数时,它会给出不可预测的结果。
因此,在指定 bbox_to_anchor时,一直都是也指定 loc

bbox_to_anchor的默认值是 (0,0,1,1),它是完整轴上的一个边界框。如果指定了不同的边界框,通常就足以使用前两个值,它们给出(x0,y0)的边界框。

下面是一个例子,其中包围框被设置为位置 (0.6,0.5)(绿点)和不同的 loc参数进行了测试。因为图例扩展到了边界框之外,所以 loc参数可能被解释为“图例的哪个角应该放置在由2元组 bbox _ to _ 锚参数给定的位置”。

enter image description here

import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = 6, 3
fig, axes = plt.subplots(ncols=3)
locs = ["upper left", "lower left", "center right"]
for l, ax in zip(locs, axes.flatten()):
ax.set_title(l)
ax.plot([1,2,3],[2,3,1], "b-", label="blue")
ax.plot([1,2,3],[1,2,1], "r-", label="red")
ax.legend(loc=l, bbox_to_anchor=(0.6,0.5))
ax.scatter((0.6),(0.5), s=81, c="limegreen", transform=ax.transAxes)


plt.tight_layout()
plt.show()

详细的解释和问题请参阅 这个答案


如果希望在轴坐标以外的其他坐标中指定图例位置,可以使用 bbox_transform参数进行此操作。如果使用图形坐标有意义的话

ax.legend(bbox_to_anchor=(1,0), loc="lower right",  bbox_transform=fig.transFigure)

使用数据坐标可能没有太大意义,但是因为您要求使用数据坐标,所以这将通过 bbox_transform=ax.transData完成。

除了@Import anceOfBeingErnest 的文章之外,我还使用下面这行来添加一个图例,它位于图表中的绝对位置。

plt.legend(bbox_to_anchor=(1.0,1.0),\
bbox_transform=plt.gcf().transFigure)

由于未知的原因,bbox_transform=fig.transFigure不与我工作。

根据 Matplotlib 图例文档:

位置也可以是一个2元组,以轴坐标表示图例左下角的坐标(在这种情况下,将忽略 Bbox _ to _ 锚)。

因此,人们可以使用:

plt.legend(loc=(x, y))

将图例的左下角设置为指定的 (x, y)位置。

请注意,这里的 xy坐标是相对的,这意味着 x=0是图中最左边的点,而 x=1是图中最右边的点。同样地,y=0y=1沿着图的高度。

我经常使用的是图例函数中的 洛克参数:

plt.legend(loc = "upper left")

如文档所述,对于字符串引用,您可以使用:

        ===============   =============
Location String   Location Code
===============   =============
'best'            0
'upper right'     1
'upper left'      2
'lower left'      3
'lower right'     4
'right'           5
'center left'     6
'center right'    7
'lower center'    8
'upper center'    9
'center'          10
===============   =============