2012-10-06 18 views
37

Ho un grafico in cui vengono utilizzati colori diversi per diversi parametri e dove vengono utilizzati stili di linea diversi per diversi algoritmi. L'obiettivo è confrontare i risultati dei diversi algoritmi eseguiti con parametri simili. Significa che in totale utilizzo 4 colori diversi e 3 stili di linea diversi, per un totale di 12 grafici sullo stesso grafico.matplotlib: 2 legende diverse sullo stesso grafico

Realizzo la legenda in base ai colori, associando ciascun colore al parametro corrispondente. Ora mi piacerebbe visualizzare una seconda legenda sullo stesso grafico, con il significato di ogni stile di linea. È possibile raggiungerlo? Come?

Ecco ciò che il mio codice è simile in realtà:

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

risposta

53

C'è una sezione nella documentazione matplotlib su questo argomento esatto: http://matplotlib.org/users/legend_guide.html#multiple-legends-on-the-same-axes

Ecco il codice per l'esempio specifico:

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) 

Ecco un esempio della sua produzione: Plot with 2 legends, per-param and per-algo

+1

Quindi la chiave è in 'add_artist' ... per qualche motivo insano Matplotlib decide che conosce meglio e cancella la legenda originale, quindi è necessario aggiungerla di nuovo in seguito. Grazie per l'aiuto, ho intenzione di bere una birra. –

5

Qui c'è anche un modo più "pratico" per farlo (ad es. interagendo esplicitamente con qualsiasi asse figura):

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) 

mi piace questo modo di scrittura in quanto potenzialmente permette di giocare con assi diversi in modo meno oscura. Puoi prima creare la tua serie di legende e poi aggiungerle agli assi che vuoi con il metodo "add_artist". Inoltre, sto iniziando con matplotlib, e per me almeno è più facile capire gli script quando gli obiettivi sono esplicitati.

NB: attenzione, le tue leggende potrebbero essere disattivate durante la visualizzazione/salvataggio. Per risolvere questo problema, utilizzare il metodo axes.set_position ([left, bottom, width, length]) per ridurre la sottotrama relativamente alle dimensioni della figura e far apparire le legende.

Problemi correlati