`plt.legend` 在 matplotlib 中,seaborn:`loc` 参数如何工作?

`plt.legend` in matplotlib, seaborn: How does the `loc` parameter work?

The strings 'upper center', 'lower center', 'center left', 'center right' place the legend at the center of the corresponding edge of the axes/figure.


代码清单

import pandas as pd
import seaborn as sb

# https://www.geeksforgeeks.org/different-ways-to-create-pandas-dataframe/
# initialize data of lists.
data = {'Name':['Tim', 'Tom', 'Cindy', 'Mandy'],
        'Age':[20, 21, 19, 18],
        'Gender':['Male', 'Male', 'Female', 'Female']}
 
# Create DataFrame
df = pd.DataFrame(data)

sb.barplot(data = df, x = 'Name', y = 'Age',  hue = 'Gender')
plt.legend(loc = 'center left', bbox_to_anchor = (1, 0.5)) # legend to right of figure

截图

(https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.legend.html)

我认为这是由于图形和轴之间的差异造成的。

Matplotlib 有两个对象:图形和轴。图是 matplotlib 正在绘制的整体图,轴是用于绘制某些内容的各个轴。例如,对于四个单独的子图,您可能有一个具有四个轴的图形。

您可以在没有轴的情况下工作,例如

plt.plot(x,y)

或带坐标轴,例如

fig, ax = plt.subplots(1,1)
ax.plot(x,y)

我相信(并且希望更有经验的人更深入地研究这种区别)通常使用轴更好,因为它可以让您在创建更复杂的图形时有更多的控制权。

那么,这与 Seaborn 有什么关系呢?好吧,我很确定 Seaborn 总是与轴一起工作。这意味着 plt.legend 正在最后使用的轴上绘制图例,而不是在 Seaborn 绘制的特定轴上。因此,正常的放置选项不起作用。

你可以做的是创建一个变量来获取 Seaborn 创建的轴,这样你就可以在该轴上绘制图例:

ax = sb.barplot(data = df, x = 'Name', y = 'Age',  hue = 'Gender')
ax.legend(loc = 'center left', bbox_to_anchor = (1, 0.5))

或者,您可以在绘图之前定义轴。

fig, ax = plt.subplots(1,1)
sb.barplot(data = df, x = 'Name', y = 'Age',  hue = 'Gender', ax=ax)
ax.legend(loc = 'center left', bbox_to_anchor = (1, 0.5))

当您还为 bbox_to_anchor 传递坐标参数时,loc 的解释会发生不直观的变化。当两者都存在时,图例框 的 loc 锚定在 bbox_to_anchor 坐标上。

所以你所做的是要求它对齐图例,使框在轴的 (1, .5) 坐标上为 left-aligned 和 vertically-centered,这将它放在外面右边的情节。

要将其放在您期望的位置,您可以 loc="center left", bbox_to_anchor=(0, .5)。或者只是不设置 bbox_to_anchor,只有当你想要 fine-tune 超出你可以在 loc 中拼出的 9 点的位置时才真正相关。例如,如果您想要轴下方 right-hand 的图例,但从角落填充一点,您可以 loc="lower right", bbox_to_anchor=(.85, .15).