停止在图例中重复标签的matplotlib

Ana*_*ake 55 matplotlib legend

这是一个非常简单的例子:

xvalues = [2,3,4,6]

for x in xvalues:
    plt.axvline(x,color='b',label='xvalues')

plt.legend()
Run Code Online (Sandbox Code Playgroud)

现在,图例将在图例中将'xvalues'显示为蓝线4次.有没有比以下更优雅的方法来解决这个问题?

for i,x in enumerate(xvalues):
    if not i:
        plt.axvline(x,color='b',label='xvalues')
    else:
        plt.axvline(x,color='b')
Run Code Online (Sandbox Code Playgroud)

eca*_*mur 90

legend将参数作为参数作为轴句柄和标签的列表,默认为plt.gca().get_legend_handles_labels().您可以在调用时删除重复的标签legend,例如:

from collections import OrderedDict
import matplotlib.pyplot as plt

handles, labels = plt.gca().get_legend_handles_labels()
by_label = OrderedDict(zip(labels, handles))
plt.legend(by_label.values(), by_label.keys())
Run Code Online (Sandbox Code Playgroud)


bli*_*bli 10

"_nolegend_"我不知道这是否可以被认为是“优雅的”,但是您可以将标签设置为首次使用后设置的变量:

my_label = "xvalues"
xvalues = [2,3,4,6]

for x in xvalues:
    plt.axvline(x, color='b', label=my_label)
    my_label = "_nolegend_"

plt.legend()
Run Code Online (Sandbox Code Playgroud)

如果您必须放置多个标签,则可以使用标签字典来概括这一点:

my_labels = {"x1" : "x1values", "x2" : "x2values"}
x1values = [1, 3, 5]
x2values = [2, 4, 6]

for x in x1values:
    plt.axvline(x, color='b', label=my_labels["x1"])
    my_labels["x1"] = "_nolegend_"
for x in x2values:
    plt.axvline(x, color='r', label=my_labels["x2"])
    my_labels["x2"] = "_nolegend_"

plt.legend()
Run Code Online (Sandbox Code Playgroud)

带有 2 个不同标签的图

(答案灵感来自/sf/answers/1357023181/


小智 6

handles, labels = ax.get_legend_handles_labels()
handle_list, label_list = [], []
for handle, label in zip(handles, labels):
    if label not in label_list:
        handle_list.append(handle)
        label_list.append(label)
plt.legend(handle_list, label_list)
Run Code Online (Sandbox Code Playgroud)

  • 请提供您的答案解释. (4认同)

A. *_*est 6

问题 - 3D 阵列

问题:2012年11月2013年10月

import numpy as np
a = np.random.random((2, 100, 4))
b = np.random.random((2, 100, 4))
c = np.random.random((2, 100, 4))
Run Code Online (Sandbox Code Playgroud)

解决方案-字典唯一性

对于我的情况_nolegend_bliDSM)不起作用,也不会label if i==0ecatmur的答案使用get_legend_handles_labels并减少了传说collections.OrderedDictFons证明了无需导入即可实现这一点。

根据这些答案,我建议使用dict独特的标签。

# Step-by-step
ax = plt.gca()                      # Get the axes you need
a = ax.get_legend_handles_labels()  # a = [(h1 ... h2) (l1 ... l2)]  non unique
b = {l:h for h,l in zip(*a)}        # b = {l1:h1, l2:h2}             unique
c = [*zip(*b.items())]              # c = [(l1 l2) (h1 h2)]
d = c[::-1]                         # d = [(h1 h2) (l1 l2)]
plt.legend(*d)
Run Code Online (Sandbox Code Playgroud)

或者

plt.legend(*[*zip(*{l:h for h,l in zip(*ax.get_legend_handles_labels())}.items())][::-1])
Run Code Online (Sandbox Code Playgroud)

也许不如Matthew Bourque的解决方案那么清晰易记。 欢迎代码高尔夫。

例子

import numpy as np
a = np.random.random((2, 100, 4))
b = np.random.random((2, 100, 4))

import matplotlib.pyplot as plt
fig, ax = plt.subplots(1)
ax.plot(*a, 'C0', label='a')
ax.plot(*b, 'C1', label='b')

ax.legend(*[*zip(*{l:h for h,l in zip(*ax.get_legend_handles_labels())}.items())][::-1])
# ax.legend()   # Old,  ^ New

plt.show()
Run Code Online (Sandbox Code Playgroud)