停止在图例中重复matplotlib标签
下面是一个非常简单的示例:停止在图例中重复matplotlib标签,matplotlib,legend,Matplotlib,Legend,下面是一个非常简单的示例: xvalues = [2,3,4,6] for x in xvalues: plt.axvline(x,color='b',label='xvalues') plt.legend() 图例现在将在图例中以蓝色线显示“xvalues”4次。 有没有比下面更优雅的方法来解决这个问题 for i,x in enumerate(xvalues): if not i: plt.axvline(x,color='b',label='xvalu
xvalues = [2,3,4,6]
for x in xvalues:
plt.axvline(x,color='b',label='xvalues')
plt.legend()
图例现在将在图例中以蓝色线显示“xvalues”4次。
有没有比下面更优雅的方法来解决这个问题
for i,x in enumerate(xvalues):
if not i:
plt.axvline(x,color='b',label='xvalues')
else:
plt.axvline(x,color='b')
plt.legend
作为参数
Artist
对象plt.gca()。获取\u图例\u句柄\u标签()
。
在调用legend
之前,您可以通过将重复标签放入字典来删除它们。这是因为dicts不能有重复的键
例如:
对于<3.7的Python版本
对于Python版本>3.7
从Python3.7开始,字典在默认情况下保留输入顺序。因此,不需要从集合模块中生成OrderedDict
import matplotlib.pyplot as plt
handles, labels = plt.gca().get_legend_handles_labels()
by_label = dict(zip(labels, handles))
plt.legend(by_label.values(), by_label.keys())
对于
plt.legend
这些代码片段对我个人来说并不适用。我正在用两种不同的颜色绘制两个不同的组。图例会显示两个红色标记和两个蓝色标记,而我只想看到每种颜色一个。我将粘贴一个简化版本的对我有用的内容:
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)
导入语句
绘图数据
添加图例
我不知道这是否算是“优雅”,但您可以在首次使用后将标签设置为变量
“\u 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()
如果必须放置多个标签,则可以使用标签字典来概括:
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()
(答案灵感来源)基于答案和
plt.gca().get_legend\u handles\u labels()[1]
提供名称列表,可以在循环打印时检查标签是否已在列表中(label=name[i]如果名称[i]不在plt.gca().get_legend\u handles\u labels()[1]其他“”
)。
对于给定的示例,此解决方案如下所示:
import matplotlib.pyplot as plt
xvalues = [2,3,4,6]
for x in xvalues:
plt.axvline(x,color='b',\
label= 'xvalues' if 'xvalues' \
not in plt.gca().get_legend_handles_labels()[1] else '')
plt.legend()
它比任何类型的循环都要短得多,而且更灵活,因为它可以单独用于循环中的任何绘图函数。
但是,对于许多循环,它可能比问题-3D阵列慢
问题:
将numpy导入为np
a=np.random.random((2100,4))
b=np.随机.随机((2100,4))
c=np.随机.随机((2100,4))
解-dict唯一性
就我的情况而言,如果i==0,则\u nolegend\u
(and)将不起作用,标签也不会起作用s answer使用get\u legend\u处理标签
,并使用collections.OrderedDict
减少图例。演示无需导入即可实现这一点
根据这些答案,我建议使用dict
作为唯一的标签
#一步一步
ax=plt.gca()#获取所需的轴
a=ax.get_legend_handles_labels()35;a=[(h1…h2)(l1…l2)]非唯一
b={l:h表示h,zip中的l(*a)}b={l1:h1,l2:h2}唯一
c=[*zip(*b.items())]#c=[(l1-l2)(h1-h2)]
d=c[:-1]#d=[(h1-h2)(l1-l2)]
零件图例(*d)
或
plt.legend(*[*zip(*{l:h代表h,l在zip中(*ax.get_legend_handles_labels())}.items())[::-1])
也许比我们的解决方案更易读、更难忘。欢迎光临
例子
将numpy导入为np
a=np.random.random((2100,4))
b=np.随机.随机((2100,4))
将matplotlib.pyplot作为plt导入
图,ax=plt子批次(1)
轴图(*a,'C0',标签='a')
轴图(*b,'C1',标签='b')
ax.legend(*[*zip(*{l:h代表h,l在zip中(*ax.get_legend_句柄_标签())}.items())[::-1])
#ax.legend()#旧,^新
plt.show()
请在回答时提供解释。我喜欢这里的答案:优雅的解决方案!这也可用于组合来自多个轴的标签。
points_dict = {points_grp: HandlerLine2D(numpoints=1),points_ctrl: HandlerLine2D(numpoints=1)}
leg = ax.legend(fontsize=12, loc='upper left', bbox_to_anchor=(1, 1.03),handler_map=points_dict)
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()
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()
import matplotlib.pyplot as plt
xvalues = [2,3,4,6]
for x in xvalues:
plt.axvline(x,color='b',\
label= 'xvalues' if 'xvalues' \
not in plt.gca().get_legend_handles_labels()[1] else '')
plt.legend()