How is order of items in matplotlib legend determined?

送分小仙女□ 提交于 2019-11-28 16:58:12

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).

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.

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

A slight variation on some other aswers. The list order should have the same length as the number of legend items, and specifies the new order manually.

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])

The following function looks for the legend handles and labels, and sorts, or partially sorts, them according to a given list (order):

#  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.mathgraph at https://gitlab.com/cpbl/cpblUtilities/blob/master/mathgraph.py

Citations: Kevin (this page) and Markus Jarderot (How do you remove duplicates from a list whilst preserving order?).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!