Ошибка атрибута легенды Python

Почему я получаю здесь ошибку, относящуюся к метке plt.plot?

fig = plt.figure()
ax = plt.gca()
barplt = plt.bar(bins,frq,align='center',label='Dgr')
normplt = plt.plot(bins_n,frq_n,'--r', label='Norm');
ax.set_xlim([min(bins)-1, max(bins)+1])
ax.set_ylim([0, max(frq)])
plt.xlabel('Dgr')
plt.ylabel('Frequency')
plt.show()
plt.legend(handles=[barplt,normplt])

Это ошибка, которую я получаю: Объект 'list' не имеет атрибута 'get_label'

Ответ 1

Поскольку plt.plot может отображать более одной строки сразу, он возвращает список объектов line2D, даже если вы только рисуете одну строку (т.е. в вашем случае - список длины 1). Когда вы берете его ручку для легенды, вы хотите использовать только первый элемент этого списка (фактический объект line2D).

Есть (по крайней мере) два способа решения этой проблемы:

1) добавьте запятую после normplt, когда вы вызываете plt.plot, чтобы сохранить только первый элемент из списка в normplt

barplt = plt.bar(bins,frq,width,align='center',label='Dgr')
normplt, = plt.plot(bins_n,frq_n,'--r', label='Norm')   # note the comma after normplt

print normplt
# Line2D(Norm)    <-- This is the line2D object, not a list, so we can use it in legend
...
plt.legend(handles=[barplt,normplt])

2) Используйте только первый элемент в списке, когда вы вызываете plt.legend (normplt[0]):

barplt = plt.bar(bins,frq,width,align='center',label='Dgr')
normplt = plt.plot(bins_n,frq_n,'--r', label='Norm')

print normplt
# [<matplotlib.lines.Line2D object at 0x112076710>]  
# Note, this is a list containing the Line2D object. We just want the object, 
# so we can use normplt[0] in legend
...
plt.legend(handles=[barplt,normplt[0]])

Ответ 2

В новой версии matplotlib (3.1.0) был добавлен новый метод создания легенд для точечных графиков.

Теперь PathCollection предоставляет метод legend_elements() для автоматического получения маркеров и меток для точечной диаграммы. Это делает создание легенды для точечного графика так же просто, как

Итак, вы также можете использовать автоматическое создание легенды:

N = 45
x, y = np.random.rand(2, N)
c = np.random.randint(1, 5, size=N)
s = np.random.randint(10, 220, size=N)

fig, ax = plt.subplots()

scatter = ax.scatter(x, y, c=c, s=s)

# produce a legend with the unique colors from the scatter
legend1 = ax.legend(*scatter.legend_elements(), loc="lower left", title="Classes")
ax.add_artist(legend1)

# produce a legend with a cross section of sizes from the scatter
handles, labels = scatter.legend_elements(prop="sizes", alpha=0.6)
legend2 = ax.legend(handles, labels, loc="upper right", title="Sizes")

plt.show()

enter image description here