2012-10-06 25 views
37

Mam działkę, w której różne kolory są używane dla różnych parametrów i gdzie różne style linii są używane dla różnych algorytmów. Celem jest porównanie wyników różnych algorytmów wykonanych z podobnymi parametrami. Oznacza to, że w sumie używam 4 różnych kolorów i 3 różnych stylów linii, co daje łącznie 12 wykresów na tym samym wykresie.matplotlib: 2 różne legendy na tym samym wykresie

Właściwie buduję legendę na podstawie kolorów, wiążąc każdy kolor z odpowiednim parametrem. Teraz chciałbym wyświetlić drugą legendę na tym samym wykresie, ze znaczeniem każdego stylu linii. Można to osiągnąć? W jaki sposób?

Oto co mój kod wygląda w rzeczywistości:

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

Odpowiedz

53

Jest sekcja w dokumentacji matplotlib na tym dokładnym przedmiotu: http://matplotlib.org/users/legend_guide.html#multiple-legends-on-the-same-axes

Oto kod dla konkretnego przykładu:

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) 

Oto przykład jego wydajności: Plot with 2 legends, per-param and per-algo

+1

Tak więc klucz znajduje się w 'add_artist' ... z jakiegoś szalonego powodu matplotlib decyduje, że wie lepiej i usuwa oryginalną legendę, a następnie musisz ją dodać później. Dzięki za pomoc, napiję się piwa. –

5

Oto także bardziej "praktyczny" sposób na zrobienie tego (tj. interakcji jawnie z dowolnej osi rysunku):

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) 

lubię ten sposób pisania, ponieważ umożliwia potencjalnie grać z różnych osi w mniej niejasny sposób. Możesz najpierw utworzyć zestaw legend, a następnie dodać je do wybranych osi za pomocą metody "add_artist". Poza tym zaczynam od matplotlib, a przynajmniej dla mnie łatwiej jest zrozumieć skrypty, gdy zostaną wyjaśnione objekty.

NB: Uważaj, twoje legendy mogą być odcięte podczas wyświetlania/zapisywania. Aby rozwiązać ten problem, użyj metody axis.set_position ([left, bottom, width, length]), aby zmniejszyć subplot w stosunku do rozmiaru rysunku i sprawić, by pojawiły się legendy.

Powiązane problemy