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

epfja78i  于 2023-05-29  发布在  其他
关注(0)|答案(5)|浏览(129)

我知道bbox_to_锚关键字和这个线程,它非常有用地建议如何手动放置图例:
How to put the legend out of the plot
但是,我想使用图形中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)

我想让我困惑的是,图例实际上并不是从0.82开始的,事实上,对于我更大的图(有5个子图),我需要使用图例坐标bbox_to_锚=(0.04,1.15,1.,.102),以便使图例出现在坐标(0.02,0.83)上。但也许我还有别的地方搞错了?

ekqde3dh

ekqde3dh1#

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_anchor参数给定的位置处”。

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()

详细解释和问题What does a 4-element tuple argument for 'bbox_to_anchor' mean in matplotlib?请参见this answer
如果要在轴坐标以外的其他坐标中指定图例位置,可以使用bbox_transform参数来执行此操作。如果使用地物坐标可能有意义

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

使用数据坐标可能没有太大意义,但既然您要求它,那么可以通过bbox_transform=ax.transData完成。

b1zrtrql

b1zrtrql2#

我经常使用的方法是在图例函数中使用 loc 参数。字符串输入工作良好:

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
        ===============   =============
xzlaal3s

xzlaal3s3#

根据matplotlib legend documentation
位置也可以是2元组,给出图例左下角的坐标坐标轴坐标(在这种情况下,*bbox_to_锚 * 将被忽略)。
因此,可以用途:

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

将图例的左下角设置为指定的(x, y)位置。
请注意,这里的xy坐标是相对的,意味着x=0是图中最左边的点,x=1是图中最右边的点。类似地,y=0y=1沿着图的高度,其中y=0是底部,y=1是顶部。

7gyucuyw

7gyucuyw4#

可以使用loc参数更改图例的位置。https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.legend.html?highlight=legend#matplotlib.axes.Axes.legend

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()
j9per5c4

j9per5c45#

除了@ImportanceOfBeingErnest的帖子之外,我还使用下面的一行在图中的绝对位置添加一个图例。

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

由于未知的原因,bbox_transform=fig.transFigure不适用于我。

相关问题