【问题标题】:Plot and Scatter legend on subplot在子图上绘制和散点图例
【发布时间】:2015-05-21 08:03:30
【问题描述】:

我的代码如下所示:

pos = 0
x = [1,2,3]
y = [2,3,4]
y2 = [3,5,3]
fig, axs = plt.subplots(1,2)
for pos in [0,1]:
    h1 = axs[pos].scatter(x,y,c='black',label='scttr')
    h2 = axs[pos].plot(x,y2,c='red',label='line')
    axs[pos].legend([h1, h2])
plt.show()

生成正确的图例,没有文本(它在句柄中显示对象名称)。如果我尝试为标签生成一些文本:

pos = 0
x = [1,2,3]
y = [2,3,4]
y2 = [3,5,3]
fig, axs = plt.subplots(1,2)
for pos in [0,1]:
    h1 = axs[pos].scatter(x,y,c='black',label='scttr')
    h2 = axs[pos].plot(x,y2,c='red',label='line')
    axs[pos].legend([h1, h2],['smtng', 'smtng2')
plt.show()

代码因以下原因崩溃:

可以使用代理艺术家代替。看: http://matplotlib.org/users/legend_guide.html#using-proxy-artist
"#using-proxy-artist".format(orig_handle))

我真的不明白 proxy artists 是什么,以及为什么我需要一个来做这么基本的事情。

【问题讨论】:

    标签: python matplotlib legend subplot


    【解决方案1】:

    问题是您不能将Line 对象直接传递给legend 调用。相反,您可以做的是创建一些不同的对象 (known as proxy artists) 来填补空白。

    下面是两个代理对象,scatter_proxyline_proxy,分别用于散点图和折线图。您使用matplotlib.lines.Line2D 创建两者,但散点图的一个有一条白线(因此没有有效地看到)并且添加了标记。我意识到将线条设置为白色有点笨拙,但这是我能找到的最好方法。

    import matplotlib.pyplot as plt
    import matplotlib.lines as mlines
    
    pos = 0
    x = [1,2,3]
    y = [2,3,4]
    y2 = [3,5,3]
    
    fig, axs = plt.subplots(1,2)
    
    scatter_color = 'black'
    line_color='red'
    
    for pos in [0,1]:
        h1 = axs[pos].scatter(x, y, c=scatter_color, label='scttr')
        h2 = axs[pos].plot(x, y2, c=line_color, label='line')
    
        scatter_proxy = mlines.Line2D([], [], color='white', marker='o', markerfacecolor=scatter_color)
        line_proxy = mlines.Line2D([], [], color=line_color)
    
        axs[pos].legend([scatter_proxy, line_proxy],['smtng', 'smtng2'])
    
    plt.show()
    

    【讨论】:

    • 不错的技巧。我用的是seaborn,你知道默认的背景颜色是什么吗?
    • @NoIdeaHowToFixThis 我已经设法使用bkgd_color = plt.rcParams['axes.facecolor'] 获得轴颜色,以使线条“不可见”,但我遇到了标记无论如何都没有出现的问题。会玩一会儿,看看我能做到什么。如果你自己修,请告诉我:P
    • 只需将线条颜色设置为'none'。那么它实际上是不可见的,独立于背景颜色
    • 这很好地修复了线条颜色,但并没有改变(使用 seaborn)标记不可见的事实。
    • @hitzg, @Ffisegydd:将线条颜色设置为 'none' 对我有用,标记仍然可见。我没有设法复制@Ffisegydd 问题。 tnx 给你们俩。
    【解决方案2】:

    至少在您的简单示例中,如果您不将任何句柄传递给legend,它会更简单:

    ...
    axs[pos].legend()
    ...
    

    结果:

    您可以像这样覆盖标签:

    ...
    axs[pos].legend(['smtng', 'smtng2'])
    ...
    

    结果:

    如果你想使用手柄,你可以。但是,您必须考虑 plot 返回 Line 对象的列表。因此,您必须像这样将其传递给legend

    ...
    axs[pos].legend([h1, h2[0]],['smtng', 'smtng2'])
    ...
    

    如果您想向图例中添加一些在您的情节中不存在的内容,或者如果您希望(出于某种原因)使其在图例中与情节中看起来不同,您只需要使用代理艺术家。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-14
      • 2022-07-28
      • 2020-08-17
      • 1970-01-01
      • 1970-01-01
      • 2022-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多