Подтвердить что ты не робот

Как определяется порядок предметов в легенде matplotlib?

Мне нужно переупорядочить элементы в легенде, когда я не думаю, что должен. Я пытаюсь:

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

и заканчивается снизу выше среднего. Как я могу получить правильный заказ? Не определяется ли это порядком создания?

Code results in the wrong legend item order

Обновление: для принудительного заказа можно использовать следующее. Я думаю, что это может быть самый простой способ сделать это, и это кажется неудобным. Вопрос в том, что определяет исходный порядок?

hh=[ht,h1,hb]
legend([ht,h1.patches[0],hb],[H.get_label() for H in hh])
4b9b3361

Ответ 1

Порядок детерминирован, но часть частных кишок поэтому может быть изменена в любое время, см. код здесь (self.* Элементы - это списки добавленных художников, поэтому список дескрипторов сортируется сначала по типу, второй - по порядку, который они добавили).

Если вы хотите явно управлять порядком элементов в вашей легенде, тогда соберите список обработчиков и меток, как вы делали в своем редактировании.

Ответ 2

Вот быстрый фрагмент для сортировки записей в легенде. Предполагается, что вы уже добавили элементы сюжета с меткой, например, что-то вроде

ax.plot(..., label='label1')
ax.plot(..., label='label2')

а затем основной бит:

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)

Это просто простая адаптация из кода, указанного в http://matplotlib.org/users/legend_guide.html

Ответ 3

Небольшое отклонение от некоторых других участников. Список 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])

Ответ 4

Следующая функция ищет маркеры и метки легенды и сортирует или частично сортирует их в соответствии с заданным списком (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))]

Функция в обновленном виде находится в cpblUtilities.mathgraph адресу https://gitlab.com/cpbl/cpblUtilities/blob/master/mathgraph.py.

Цитаты: Кевин (эта страница) и Маркус Жардерот (Как вы удаляете дубликаты из списка, сохраняя порядок?).