matplotlib中图例中的项目是否重复?

23 python matplotlib

我想用这个片段将图例添加到我的情节中:

import matplotlib.pylab as plt

fig = plt.figure()
axes = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # left, bottom, width, height (range 0 to 1)
axes.set_xlabel('x (m)')
axes.set_ylabel('y (m)')
for i, representative in enumerate(representatives):
    axes.plot([e[0] for e in representative], [e[1] for e in representative], color='b', label='Representatives')
axes.scatter([e[0] for e in intersections], [e[1] for e in intersections], color='r', label='Intersections')
axes.legend()   
Run Code Online (Sandbox Code Playgroud)

我最终得到了这个情节

在此输入图像描述

显然,这些项目在图中是重复的.我该如何更正此错误?

DSM*_*DSM 46

正如文档所说,虽然很容易错过:

如果label属性为空字符串或以"_"开头,则将忽略这些艺术家.

因此,如果我在循环中绘制类似的线条并且我只想在图例中使用一个示例线,我通常会做类似的事情

ax.plot(x, y, label="Representatives" if i == 0 else "")
Run Code Online (Sandbox Code Playgroud)

i我的循环索引在哪里.

看起来单独构建它们并不是很好,但我常常希望标签逻辑尽可能靠近线条图.

(请注意,matplotlib开发人员自己倾向于使用"_nolegend_"显式.)


Fon*_*ons 25

根据EL_DON 的回答,这里是绘制没有重复标签的图例的一般方法

def legend_without_duplicate_labels(ax):
    handles, labels = ax.get_legend_handles_labels()
    unique = [(h, l) for i, (h, l) in enumerate(zip(handles, labels)) if l not in labels[:i]]
    ax.legend(*zip(*unique))

Run Code Online (Sandbox Code Playgroud)

实例:开放中repl.it

fig, ax = plt.subplots()

ax.plot([0,1], [0,1], c="y", label="my lines")
ax.plot([0,1], [0,2], c="y", label="my lines")

legend_without_duplicate_labels(ax)

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

在此处输入图片说明


EL_*_*DON 7

这是一种在正常分配标签后删除重复的图例条目的方法:

representatives=[[[-100,40],[-50,20],[0,0],[75,-5],[100,5]], #made up some data
                 [[-60,80],[0,85],[100,90]],
                 [[-60,15],[-50,90]],
                 [[-2,-2],[5,95]]]
fig = plt.figure()
axes = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # left, bottom, width, height (range 0 to 1)
axes.set_xlabel('x (m)')
axes.set_ylabel('y (m)')
for i, representative in enumerate(representatives):
    axes.plot([e[0] for e in representative], [e[1] for e in representative],color='b', label='Representatives')
#make sure only unique labels show up (no repeats)
handles,labels=axes.get_legend_handles_labels() #get existing legend item handles and labels
i=arange(len(labels)) #make an index for later
filter=array([]) #set up a filter (empty for now)
unique_labels=tolist(set(labels)) #find unique labels
for ul in unique_labels: #loop through unique labels
    filter=np.append(filter,[i[array(labels)==ul][0]]) #find the first instance of this label and add its index to the filter
handles=[handles[int(f)] for f in filter] #filter out legend items to keep only the first instance of each repeated label
labels=[labels[int(f)] for f in filter]
axes.legend(handles,labels) #draw the legend with the filtered handles and labels lists
Run Code Online (Sandbox Code Playgroud)

以下是结果: 在此输入图像描述 左边是上面脚本的结果.在右侧,图例调用已被替换为axes.legend().

优点是您可以查看大部分代码并正常分配标签,而不用担心内联循环或ifs.您还可以将其构建为包含图例或类似内容的包装器.


Jul*_*n J 6

这是一个向图形添加图例且不重复的函数:

def legend_without_duplicate_labels(figure):
    handles, labels = plt.gca().get_legend_handles_labels()
    by_label = dict(zip(labels, handles))
    figure.legend(by_label.values(), by_label.keys(), loc='lower right')
Run Code Online (Sandbox Code Playgroud)

然后我们可以在下面的示例中使用它:

import matplotlib.pyplot as plt

plt.plot([0,3], [0,1], c="red", label="line")
plt.plot([0,3], [0,2], c="red", label="line")
legend_without_duplicate_labels(plt)
plt.show()
Run Code Online (Sandbox Code Playgroud)

结果

数字