Matplotlib: 2 разных легенды на одном графике
У меня есть график, в котором для разных параметров используются разные цвета, а для разных алгоритмов используются разные стили линий. Целью является сравнение результатов различных алгоритмов, выполняемых с аналогичными параметрами. Это означает, что в общей сложности я использую 4 разных цвета и 3 разных стиля линий, в общей сложности 12 графиков на одном графике.
Я фактически создаю легенду на основе цветов, сопоставляя каждый цвет с соответствующим параметром. Теперь я хотел бы отобразить вторую легенду на том же графике со значением каждого стиля линии. Этого можно достичь? Как?
Вот как выглядит мой код:
colors = ['b', 'r', 'g', 'c']
cc = cycle(c)
for p in parameters:
d1 = algo1(p)
d2 = algo2(p)
d3 = algo3(p)
pyplot.hold(True)
c = next(cc)
pyplot.plot(d1, '-', color=c, label="d1")
pyplot.plot(d1, '--', color=c)
pyplot.plot(d2, '.-', color=c)
pyplot.legend()
Ответы
Ответ 1
В документации matplotlib по этому предмету есть раздел: http://matplotlib.org/users/legend_guide.html#multiple-legends-on-the-same-axes
Здесь код для вашего конкретного примера:
import itertools
from matplotlib import pyplot
colors = ['b', 'r', 'g', 'c']
cc = itertools.cycle(colors)
plot_lines = []
for p in parameters:
d1 = algo1(p)
d2 = algo2(p)
d3 = algo3(p)
pyplot.hold(True)
c = next(cc)
l1, = pyplot.plot(d1, '-', color=c)
l2, = pyplot.plot(d2, '--', color=c)
l3, = pyplot.plot(d3, '.-', color=c)
plot_lines.append([l1, l2, l3])
legend1 = pyplot.legend(plot_lines[0], ["algo1", "algo2", "algo3"], loc=1)
pyplot.legend([l[0] for l in plot_lines], parameters, loc=4)
pyplot.gca().add_artist(legend1)
Здесь пример его вывода:
![Plot with 2 legends, per-param and per-algo]()
Ответ 2
Здесь также более "практический" способ сделать это (т.е. явно взаимодействовать с любыми осями фигур):
import itertools
from matplotlib import pyplot
fig, axes = plt.subplot(1,1)
colors = ['b', 'r', 'g', 'c']
cc = itertools.cycle(colors)
plot_lines = []
for p in parameters:
d1 = algo1(p)
d2 = algo2(p)
d3 = algo3(p)
c = next(cc)
axes.plot(d1, '-', color=c)
axes.plot(d2, '--', color=c)
axes.plot(d3, '.-', color=c)
# In total 3x3 lines have been plotted
lines = axes.get_lines()
legend1 = pyplot.legend([lines[i] for i in [0,1,2]], ["algo1", "algo2", "algo3"], loc=1)
legend2 = pyplot.legend([lines[i] for i in [0,3,6]], parameters, loc=4)
axes.add_artist(legend1)
axes.add_artist(legend2)
Мне нравится этот способ написания, так как он позволяет потенциально играть с разными осями менее неясным образом. Вы можете сначала создать свой набор легенд, а затем добавить их к осям, которые вы хотите, с помощью метода "add_artist". Кроме того, я начинаю с matplotlib, и для меня, по крайней мере, легче понять скрипты, когда objets объясняются.
Примечание. Будьте осторожны, ваши легенды могут быть обрезаны при отображении/сохранении. Чтобы решить эту проблему, используйте метод axes.set_position ([left, bottom, width, length]), чтобы уменьшить размер шрифта относительно размера фигуры и сделать легенды.