2012-10-06 41 views
37

Tengo un gráfico en el que se usan colores diferentes para diferentes parámetros, y donde se usan diferentes estilos de línea para diferentes algoritmos. El objetivo es comparar los resultados de los diferentes algoritmos realizados con parámetros similares. Significa que utilizo en total 4 colores diferentes y 3 estilos de línea diferentes, para un total de 12 gráficos en el mismo gráfico.matplotlib: 2 leyendas diferentes en el mismo gráfico

De hecho construyo la leyenda basada en colores, asociando cada color con el parámetro correspondiente. Ahora me gustaría mostrar una segunda leyenda en el mismo gráfico, con el significado de cada estilo de línea. Es posible lograr eso? ¿Cómo?

Esto es lo que se ve mi código como realidad:

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

Respuesta

53

Hay una sección en la documentación matplotlib en ese tema exacto: http://matplotlib.org/users/legend_guide.html#multiple-legends-on-the-same-axes

Aquí está el código para su ejemplo específico:

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) 

Aquí hay un ejemplo de su salida: Plot with 2 legends, per-param and per-algo

+1

Así que la clave está en 'add_artist' ... por alguna razón loca matplotlib decide que sabe mejor y elimina la leyenda original, luego debe agregarla más tarde. Gracias por la ayuda, voy a tomar una cerveza. –

5

Aquí también hay una forma más práctica de hacerlo (es decir interactuar con cualquier explícitamente ejes 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) 

me gusta esta forma de escribirlo, ya que permite potencialmente a jugar con diferentes ejes de una manera menos oscuro. Primero puede crear su conjunto de leyendas y luego agregarlas a los ejes que desee con el método "add_artist". Además, estoy comenzando con matplotlib, y para mí, al menos, es más fácil entender los guiones cuando se explicitan los objetos.

NB: Tenga cuidado, sus leyendas pueden cortarse mientras se muestran/guardan. Para resolver este problema, utilice el método axes.set_position ([left, bottom, width, length]) para reducir la subparcela en relación con el tamaño de la figura y hacer que aparezcan las leyendas.

Cuestiones relacionadas