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() 

В документации 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) 

Вот пример его вывода: Участок с двумя легендами, за-парам и пер-алго

Здесь также более «практический» способ сделать это (т. Е. Взаимодействовать явно с любыми осями фигур):

 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 будут раскрыты.

NB: Будьте осторожны, ваши легенды могут быть обрезаны при отображении / сохранении. Чтобы решить эту проблему, используйте метод axes.set_position ([left, bottom, width, length]), чтобы уменьшить размер шрифта относительно размера фигуры и сделать легенды.