цвета в легенде не соответствуют цветам графика - PullRequest
1 голос
/ 21 мая 2019

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

legend 3 should be blue (0) and green (2)

Вот mwe, который я использовал для генерации изображения, но учтите, что в реальной программе функция plot не доступна напрямую и загружается из другого файла. Кроме того, функция сюжета не должна изменяться, так как она используется и в других программах.

import matplotlib.pyplot as plt
import numpy as np

def my_plot_function(x,y,ax):
    #do complicated stuff here, manipulating y for example
    ax.plot(x,y)

x = np.linspace(0,1,100)
fig = plt.figure()
ax = fig.add_subplot(111)

my_plot_function(x, x, ax)
my_plot_function(x, x**2, ax)
my_plot_function(x, x**3, ax)
my_plot_function(x, x**4, ax)

lines = ax.get_lines()
print(lines[0])
print(lines[1])
print(lines[2])
print(lines[3])

fig.legend(lines, labels=range(4), loc=1, title="legend 1")
fig.legend([lines[0],lines[1]], labels=["0","1"], loc=2, title="legend 2")
fig.legend([lines[0],lines[2]], labels=["0","2"], loc=3, title="legend 3")
plt.show()

EDIT:
Чтобы уточнить, о чем я просил: составление графика должно выполняться с помощью my_plot_function, который определен в отдельном файле и не может быть изменен. Поэтому я не могу передать ему дополнительные ключевые слова, такие как label.

Ответы [ 4 ]

4 голосов
/ 21 мая 2019

Я бы подошел к проблеме немного по-другому.В таких случаях, как ваш, я бы всегда рекомендовал пропустить запись легенды при построении с использованием ключевого слова label.Затем, чтобы использовать выбранные легенды, вы можете использовать get_legend_handles_labels(), а затем передать необходимые элементы в fig.legend().Вам не нужно указывать аргументы handles и labels.Но если вы укажете один (как вы сделали для labels), вам также следует указать другой, иначе вы получите предупреждение

import matplotlib.pyplot as plt
import numpy as np

def plot(x,y,ax):
    ax.plot(x,y)

x = np.linspace(0,1,100)
fig = plt.figure()
ax = fig.add_subplot(111)

ax.plot(x, x, label='0')
ax.plot(x, x**2, label='1')
ax.plot(x, x**3, label='2')
ax.plot(x, x**4, label='3')
ax.legend(loc=1, title='legend 1')

h, l = ax.get_legend_handles_labels()

fig.legend([h[0],h[1]], [l[0], l[1]], loc=2, title="legend 2")
fig.legend([h[0],h[2]], [l[0], l[2]], loc=3, title="legend 3")
plt.show() 

enter image description here

Альтернативный подход к ответу на комментарий @gboffi ниже заключается в том, что вы не используете глобальную легенду для извлечения значений.

x = np.linspace(0,1,100)
fig = plt.figure()
ax = fig.add_subplot(111)

l0, = ax.plot(x, x, label='0')
l1, = ax.plot(x, x**2, label='1')
l2, = ax.plot(x, x**3, label='2')
l3, = ax.plot(x, x**4, label='3')

fig.legend([l0, l1], [l0.get_label(), l1.get_label()], loc=2, title="legend 2")
fig.legend([l0, l2], [l0.get_label(), l2.get_label()], loc=3, title="legend 3")
plt.show() 
1 голос
/ 21 мая 2019

Использовать handles аргумент ключевого слова:

fig.legend(handles=lines, labels=range(4), loc=1, title="legend 1")
fig.legend(handles=[lines[0],lines[1]], labels=["0","1"], loc=2, title="legend 2")
fig.legend(handles=[lines[0],lines[2]], labels=["0","2"], loc=3, title="legend 3")
1 голос
/ 21 мая 2019

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

Это работает

fig.legend(lines, range(4), loc=1, title="legend 1")
fig.legend((lines[0],lines[1]), ("0","1"), loc=2, title="legend 2")
fig.legend((lines[0],lines[2]), ("0","2"), loc=3, title="legend 3")

и это работает

fig.legend(handles=lines, labels=range(4), loc=1, title="legend 1")
fig.legend(handles=(lines[0],lines[1]), labels=("0","1"), loc=2, title="legend 2")
fig.legend(handles=(lines[0],lines[2]), labels=("0","2"), loc=3, title="legend 3")
1 голос
/ 21 мая 2019

Когда я запускаю ваш код, я получаю предупреждение от legend.py:

UserWarning: You have mixed positional and keyword arguments, some input may be discarded.
  warnings.warn("You have mixed positional and keyword "...

Возможно, это причина того, что она не работает. Вам нужно добавить handlers в ваши вызовы легенды. * Т.е. 1006 *

fig.legend(handlers=[lines[0],lines[1]],...

Кстати, хорошей практикой является назначение метки при создании графика.

ax.plot(x, y, label='some label')

Тогда вы можете позвонить

handles, labels = ax.get_legend_handles_labels()

и используйте их в легенде, вот так

fig.legend(handles=(handles[0],handles[2]), labels=(labels[0],labels[2]),...)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...