Сюжет и легенда разброса на подзаголовке

Мой код выглядит так:

pos = 0
x = [1,2,3]
y = [2,3,4]
y2 = [3,5,3]
fig, axs = plt.subplots(1,2)
for pos in [0,1]:
    h1 = axs[pos].scatter(x,y,c='black',label='scttr')
    h2 = axs[pos].plot(x,y2,c='red',label='line')
    axs[pos].legend([h1, h2])
plt.show()

который создает правую легенду без текста (показывает имя объекта в дескрипторе). Если я попытаюсь создать текст для меток:

pos = 0
x = [1,2,3]
y = [2,3,4]
y2 = [3,5,3]
fig, axs = plt.subplots(1,2)
for pos in [0,1]:
    h1 = axs[pos].scatter(x,y,c='black',label='scttr')
    h2 = axs[pos].plot(x,y2,c='red',label='line')
    axs[pos].legend([h1, h2],['smtng', 'smtng2')
plt.show()

код вылетает со следующим:

Вместо этого можно использовать прокси-исполнителя. См .: http://matplotlib.org/users/legend_guide.html#using-proxy-artist
"# using-proxy-artist" .format (orig_handle))

Я действительно не понимал, что такое прокси-исполнители и зачем они мне нужны для такой простой вещи.


person NoIdeaHowToFixThis    schedule 18.03.2015    source источник


Ответы (2)


Проблема в том, что вы не можете передать Line объекты напрямую вызову legend. Вместо этого вы можете создать несколько разных объектов (известные как proxy-исполнители), чтобы, так сказать, восполнить пробел.

Ниже представлены два прокси-объекта, scatter_proxy и line_proxy, для диаграммы рассеяния и линейной диаграммы соответственно. Вы создаете оба, используя matplotlib.lines.Line2D, но один для диаграммы рассеяния имеет белая линия (поэтому не видна эффективно) и к ней добавлены маркеры. Я понимаю, что делать цвет линии белым - это немного хакерство, но это был лучший способ, который я мог найти.

import matplotlib.pyplot as plt
import matplotlib.lines as mlines

pos = 0
x = [1,2,3]
y = [2,3,4]
y2 = [3,5,3]

fig, axs = plt.subplots(1,2)

scatter_color = 'black'
line_color='red'

for pos in [0,1]:
    h1 = axs[pos].scatter(x, y, c=scatter_color, label='scttr')
    h2 = axs[pos].plot(x, y2, c=line_color, label='line')

    scatter_proxy = mlines.Line2D([], [], color='white', marker='o', markerfacecolor=scatter_color)
    line_proxy = mlines.Line2D([], [], color=line_color)

    axs[pos].legend([scatter_proxy, line_proxy],['smtng', 'smtng2'])

plt.show()

введите описание изображения здесь

person Ffisegydd    schedule 18.03.2015
comment
хороший хак. Я использую seaborn, знаете ли вы, какой цвет фона установлен по умолчанию? - person NoIdeaHowToFixThis; 18.03.2015
comment
@NoIdeaHowToFixThis Мне удалось получить цвет осей, используя bkgd_color = plt.rcParams['axes.facecolor'], чтобы сделать линию невидимой, но у меня проблема с тем, что маркеры все равно не появляются. Немного поиграюсь и посмотрю, что у меня получится. Если почините сами, дайте знать: P - person Ffisegydd; 18.03.2015
comment
Просто установите цвет линии на 'none'. Тогда он фактически невидим независимо от цвета фона. - person hitzg; 18.03.2015
comment
Это хорошо исправляет цвет линии, но не меняет того факта, что (с морским рисунком) маркеры не видны. - person Ffisegydd; 18.03.2015
comment
@hitzg, @Ffisegydd: установка цвета линии на 'none' у меня сработала, и маркеры остаются видимыми. Мне не удалось воспроизвести проблему @Ffisegydd. Спасибо вам обоим. - person NoIdeaHowToFixThis; 19.03.2015
comment
@NoIdeaHowToFix Это ты мой ответ видел? Вы можете сделать это без прокси-художников (см. Последнюю часть моего ответа) - person hitzg; 19.03.2015

По крайней мере, в вашем простом примере это будет проще, если вы не передадите никаких дескрипторов в legend:

...
axs[pos].legend()
...

Результат:

введите описание изображения здесь

Вы можете перезаписать метки следующим образом:

...
axs[pos].legend(['smtng', 'smtng2'])
...

Результат: введите описание изображения здесь

Если вы хотите использовать ручки, вы можете. Однако вы должны учитывать, что plot возвращает список объектов Line. Таким образом, вы должны передать его legend следующим образом:

...
axs[pos].legend([h1, h2[0]],['smtng', 'smtng2'])
...

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

person hitzg    schedule 18.03.2015