matplotlib: 2 légendes différentes sur un même graphique
j'ai un graphique où différentes couleurs sont utilisées pour différents paramètres, et où différents styles de ligne sont utilisés pour différents algorithmes. L'objectif est de comparer les résultats des différents algorithmes réalisée avec des paramètres similaires. Cela signifie au total que j'utilise 4 couleurs différentes, et 3 styles de ligne différents, pour un total de 12 tracés sur le même graphique.
je construis en fait la légende basée sur les couleurs, en associant chaque couleur avec le paramètre correspondant. Maintenant, je voudrais afficher une deuxième légende sur le même graphique, avec la signification de chaque ligne de style. Il est possible d'y parvenir? Comment?
voici à quoi ressemble en fait mon code:
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()
2 réponses
Il y a une section dans la documentation de matplotlib sur ce sujet précis: http://matplotlib.org/users/legend_guide.html#multiple-legends-on-the-same-axes
Voici le code pour votre exemple:
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)
Voici un exemple de sa sortie:

voici aussi une façon plus "pratique" de le faire (c.-à-d. interagir explicitement avec n'importe quel axe de la figure):
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)
j'aime cette façon de l'écrire car elle permet potentiellement de jouer avec différents axes d'une manière moins obscure. Vous pouvez d'abord créer votre jeu de légendes, puis les ajouter à la axes que vous voulez avec la méthode "add_artist". Aussi, je commence avec matplotlib, et pour moi au moins il est plus facile de comprendre les scripts quand les objets sont explicités.
NB: Be attention, vos légendes peuvent être coupées lors de l'affichage/sauvegarde. Pour résoudre ce problème, utilisez la méthode axes.set_position ([left, bottom, width, length]) pour rétrécir la sous-parcelle relativement à la taille de la figure et faire apparaître les légendes.