【问题标题】:Matplotlib: order of legend entriesMatplotlib:图例条目的顺序
【发布时间】:2021-07-06 01:02:41
【问题描述】:

我最近发现 matplotlib 是 Matlab 绘图的更好替代品。不幸的是,我对python的了解接近于零。

考虑以下最小的工作示例:我希望图例中的条目按照声明它们的顺序出现。我从this post 了解到,条目首先根据类型排序,然后根据顺序(在这种情况下,两个线图总是在散点图之前)。

我尝试将上述帖子中的方法应用到我的示例中,即创建句柄并将它们传递给plt.legend,但它不起作用。不幸的是,我这样做很盲目,因为我不完全理解我在做什么,所以这可能是错误的方法或一些语法错误。如何调整下面的简单代码来强制执行所需的图例顺序?

import numpy as np
import scipy.io
from matplotlib import pyplot as plt

plt.figure(figsize=[3.3, 3.3])
plt.rcParams.update({'font.size': 8, 'text.usetex': True})

plt.scatter([1, 2, 3], [5, 10, 15], label='1st entry')
plt.plot([1, 2, 3, 4], [1, 4, 9, 16], label='2nd entry')
plt.plot([1, 2, 3, 4], [1, 2, 3, 4], label='3st entry')

plt.grid()
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc='lower right', labelspacing=0.25, handlelength=0.4, handletextpad=0.7)

plt.savefig('filename.pdf', format='pdf')

plt.show()

【问题讨论】:

    标签: python matplotlib legend


    【解决方案1】:

    有一个解决方案(但我觉得它不是很优雅),包括在 matplotlib 自动生成图例之后重新排序:

    fig = plt.figure(figsize=[3.3, 3.3])
    ax = fig.add_subplot(111)
    plt.rcParams.update({'font.size': 8, 'text.usetex': True})
    
    ax.scatter([1, 2, 3], [5, 10, 15], label='1st entry')
    ax.plot([1, 2, 3, 4], [1, 4, 9, 16], label='2nd entry')
    ax.plot([1, 2, 3, 4], [1, 2, 3, 4], label='3rd entry')
    
    ax.grid()
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    
    handles,labels = ax.get_legend_handles_labels()
    
    handles = [handles[2], handles[0], handles[1]]
    labels = [labels[2], labels[0], labels[1]]
    
    ax.legend(handles,labels,loc='lower right', labelspacing=0.25, handlelength=0.4, handletextpad=0.7)
    

    编辑:在评论中,OP 要求一个没有明确创建轴的版本,在这里(但我建议习惯使用轴来制作更高级的图):

    plt.figure(figsize=[3.3, 3.3])
    plt.rcParams.update({'font.size': 8, 'text.usetex': True})
    
    plt.scatter([1, 2, 3], [5, 10, 15], label='1st entry')
    plt.plot([1, 2, 3, 4], [1, 4, 9, 16], label='2nd entry')
    plt.plot([1, 2, 3, 4], [1, 2, 3, 4], label='3rd entry')
    
    plt.grid()
    plt.xlabel('x')
    plt.ylabel('y')
    
    handles,labels = plt.gca().get_legend_handles_labels()
    
    handles = [handles[2], handles[0], handles[1]]
    labels = [labels[2], labels[0], labels[1]]
    
    plt.legend(handles,labels,loc='lower right', labelspacing=0.25, handlelength=0.4, handletextpad=0.7)
    

    【讨论】:

    • 感谢您的回答。有没有办法在不替换“plt”的情况下做同样的事情。用“斧头”。无处不在?
    • handles[::-1]您可以像这样以相反的顺序指定列表。
    • @TheDon 我编辑了我的答案以添加一个没有显式使用轴变量的版本,但我建议你在接下来的旅程中使用 matplotlib 来习惯它;-)
    • 非常感谢!它完美地工作。如果您能(非常简短地)解释为什么我应该使用“ax”,我将不胜感激。而不是“plt”。
    • 非常简单:使用plt. 非常适合快速绘制单个绘图,但只要您想要对其进行微调,或者在第一个绘图下方或旁边添加第二个绘图以获取上下文,使用ax. 会容易得多。这就是为什么,即使对于单个地块,我现在也使用ax.,以便从那里轻松扩充。但这可能是一种非常个人化的方法;-)
    猜你喜欢
    • 2023-01-16
    • 1970-01-01
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 2019-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多