Python matplotlib图例中的项目顺序是如何确定的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22263807/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How is order of items in matplotlib legend determined?
提问by CPBL
I am having to reorder items in a legend, when I don't think I should have to. I try:
我不得不重新排序图例中的项目,而我认为我不应该这样做。我尝试:
from pylab import *
clf()
ax=gca()
ht=ax.add_patch(Rectangle((1,1),1,1,color='r',label='Top',alpha=.01))
h1=ax.bar(1,2,label='Middle')
hb=ax.add_patch(Rectangle((1,1),1,1,color='k',label='Bottom',alpha=.01))
legend()
show()
and end up with Bottom above Middle. How can I get the right order? Is it not determined by creation order?
并以底部高于中间结束。我怎样才能得到正确的订单?不是由创建顺序决定的吗?


Update: The following can be used to force the order. I think this may be the simplest way to do it, and that seems awkward. The question is what determines the original order?
更新:以下可用于强制排序。我认为这可能是最简单的方法,这看起来很尴尬。问题是什么决定了原始顺序?
hh=[ht,h1,hb]
legend([ht,h1.patches[0],hb],[H.get_label() for H in hh])
采纳答案by tacaswell
The order is deterministic, but part of the private guts so can be changed at any time, see the code here(the self.*elements are lists of the artists that have been added, hence the handle list is sorted first by type, second by order they were added).
顺序是确定性的,但部分私有内容可以随时更改,请参阅此处的代码(self.*元素是已添加艺术家的列表,因此句柄列表首先按类型排序,其次按顺序排序)添加)。
If you want to explicitly control the order of the elements in your legend then assemble a list of handlers and labels like you did in the your edit.
如果您想明确控制图例中元素的顺序,请像在编辑中所做的那样组合处理程序和标签的列表。
回答by kevin
Here's a quick snippet to sort the entries in a legend. It assumes that you've already added your plot elements with a label, for example, something like
这是对图例中的条目进行排序的快速片段。它假设您已经添加了带有标签的绘图元素,例如,类似
ax.plot(..., label='label1')
ax.plot(..., label='label2')
and then the main bit:
然后是主要部分:
handles, labels = ax.get_legend_handles_labels()
# sort both labels and handles by labels
labels, handles = zip(*sorted(zip(labels, handles), key=lambda t: t[0]))
ax.legend(handles, labels)
This is just a simple adaptation from the code listed at http://matplotlib.org/users/legend_guide.html
这只是对http://matplotlib.org/users/legend_guide.html 中列出的代码的简单改编
回答by CPBL
The following function makes control of legend order easy and readable.
以下函数使图例顺序的控制变得容易和可读。
You can specify the order you want by label. It will find the legend handles and labels, drop duplicate labels, and sort or partially sort them according to your given list (order). So you use it like this:
您可以通过标签指定所需的顺序。它将找到图例句柄和标签,删除重复的标签,并根据给定的列表 ( order)对它们进行排序或部分排序。所以你像这样使用它:
reorderLegend(ax,['Top', 'Middle', 'Bottom'])
Details are below.
详情如下。
# Returns tuple of handles, labels for axis ax, after reordering them to conform to the label order `order`, and if unique is True, after removing entries with duplicate labels.
def reorderLegend(ax=None,order=None,unique=False):
if ax is None: ax=plt.gca()
handles, labels = ax.get_legend_handles_labels()
labels, handles = zip(*sorted(zip(labels, handles), key=lambda t: t[0])) # sort both labels and handles by labels
if order is not None: # Sort according to a given list (not necessarily complete)
keys=dict(zip(order,range(len(order))))
labels, handles = zip(*sorted(zip(labels, handles), key=lambda t,keys=keys: keys.get(t[0],np.inf)))
if unique: labels, handles= zip(*unique_everseen(zip(labels,handles), key = labels)) # Keep only the first of each handle
ax.legend(handles, labels)
return(handles, labels)
def unique_everseen(seq, key=None):
seen = set()
seen_add = seen.add
return [x for x,k in zip(seq,key) if not (k in seen or seen_add(k))]
The function in updated form is in cpblUtilities.mathgraphat https://gitlab.com/cpbl/cpblUtilities/blob/master/mathgraph.py
更新形式的函数cpblUtilities.mathgraph位于https://gitlab.com/cpbl/cpblUtilities/blob/master/mathgraph.py
Usage is thus like this:
用法是这样的:
fig, ax = plt.subplots(1)
ax.add_patch(Rectangle((1,1),1,1,color='r',label='Top',alpha=.01))
ax.bar(1,2,label='Middle')
ax.add_patch(Rectangle((1,1),1,1,color='k',label='Bottom',alpha=.01))
legend()
reorderLegend(ax,['Top', 'Middle', 'Bottom'])
show()
The optional uniqueargument makes sure to drop duplicate plot objects which have the same label.
可选unique参数确保删除具有相同标签的重复绘图对象。
回答by Ian Hincks
A slight variation on some other aswers. The list ordershould have the same length as the number of legend items, and specifies the new order manually.
其他一些答案略有不同。该列表order的长度应与图例项的数量相同,并手动指定新顺序。
handles, labels = plt.gca().get_legend_handles_labels()
order = [0,2,1]
plt.legend([handles[idx] for idx in order],[labels[idx] for idx in order])

