【问题标题】:`plt.legend` in matplotlib, seaborn: How does the `loc` parameter work?matplotlib 中的“plt.legend”,seaborn:“loc”参数如何工作?
【发布时间】:2022-01-23 23:16:22
【问题描述】:
  • 我是 Python 的初学者,正在学习在线课程。以下是课程中给定解决方案的抽象版本。
  • 在一个练习中,生成了一个seaborn 图并添加了一个legend
  • 问题:根据使用的参数,我不明白图例在右侧的情况。 loc = 'center left' 是如何将legend 放在情节右侧的?
  • matplotlib manual 说:

字符串 'upper center', 'lower center', 'center left', 'center right' 将图例放置在相应边缘的中心 轴/图。

  • 我确信有一个合乎逻辑的答案,但我看不到它:)。

代码清单

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)

【问题讨论】:

    标签: python matplotlib seaborn


    【解决方案1】:

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

    因此,您所做的是要求它对齐图例,使框左对齐并垂直居中于轴的 (1, .5) 坐标上,这将其置于右侧的绘图之外.

    要将其放在您期望的位置,您可以使用loc="center left", bbox_to_anchor=(0, .5)。或者只是不设置bbox_to_anchor,这仅在您想要将位置微调到您可以在loc 中拼出的9 个点之外才真正相关。例如,如果您想要轴右下角的图例,但从角落填充一点,您可以使用loc="lower right", bbox_to_anchor=(.85, .15)

    【讨论】:

    • 啊,谢谢,这是有用的信息。文档对我来说没有意义。
    • 是的,我同意。如果您了解默认 bbox_to_anchor 工作原理的详细信息,则该行为是合乎逻辑的,即使它不直观,但我认为文档中您突出显示的部分不正确或充其量是误导。
    【解决方案2】:

    我相信这是由于图形和轴之间的差异。

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

    【讨论】:

    • 我给了答案+1,谢谢!但是想等别人回复我才接受答案。我松了一口气,这对你来说也很奇怪。
    • 没问题,我不介意自己看到另一种解释,因为我是自学成才的,而且我的知识有很多空白。请放心,即使在使用 MPL/Seaborn 绘制了数千次之后,我仍然会遇到您所描述的问题。例如,为使用 seaborn 绘制的多个子图获取单个图例并不是一项简单的任务!
    • 这个答案实际上是不正确的。 Plt.legend 使用最后使用的轴。但是一般来说,最好使用显式接口而不是 pyplot。
    猜你喜欢
    • 2019-12-25
    • 2023-03-06
    • 2023-03-12
    • 2016-08-25
    • 1970-01-01
    • 2022-12-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    相关资源
    最近更新 更多