Ошибка атрибута легенды 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]()