web-dev-qa-db-fra.com

Comment attribuer plusieurs étiquettes à la fois dans matplotlib?

J'ai le jeu de données suivant:

x = [0, 1, 2, 3, 4]
y = [ [0, 1, 2, 3, 4],
      [5, 6, 7, 8, 9],
      [9, 8, 7, 6, 5] ]

Maintenant, je l'intrigue avec:

import matplotlib.pyplot as plt
plt.plot(x, y)

Cependant, je veux étiqueter les 3 jeux de données y avec cette commande, ce qui déclenche une erreur lorsque .legend() est appelée:

lineObjects = plt.plot(x, y, label=['foo', 'bar', 'baz'])
plt.legend()

File "./plot_nmos.py", line 33, in <module>
  plt.legend()
...
AttributeError: 'list' object has no attribute 'startswith'

Lorsque j'inspecte le lineObjects:

>>> lineObjects[0].get_label()
['foo', 'bar', 'baz']
>>> lineObjects[1].get_label()
['foo', 'bar', 'baz']
>>> lineObjects[2].get_label()
['foo', 'bar', 'baz']

Question

Existe-t-il un moyen élégant d'attribuer plusieurs étiquettes en utilisant simplement la méthode .plot()?

46
Kit

Il n'est pas possible de tracer ces deux tableaux directement l'un contre l'autre (avec au moins la version 1.1.1), vous devez donc effectuer une boucle sur vos tableaux y. Mon conseil serait de parcourir les étiquettes en même temps:

import matplotlib.pyplot as plt

x = [0, 1, 2, 3, 4]
y = [ [0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [9, 8, 7, 6, 5] ]
labels = ['foo', 'bar', 'baz']

for y_arr, label in Zip(y, labels):
    plt.plot(x, y_arr, label=label)

plt.legend()
plt.show()

Edit: @gcalmettes a souligné qu'en tant que tableaux numpy, il est possible de tracer toutes les lignes en même temps (en les transposant). Voir la réponse et les commentaires de @gcalmettes pour plus de détails.

36
pelson

Vous pouvez parcourir votre liste d'objets de ligne afin que les étiquettes soient affectées individuellement. Un exemple avec la fonction intégrée python iter:

lineObjects = plt.plot(x, y)
plt.legend(iter(lineObjects), ('foo', 'bar', 'baz'))`

Edit: après la mise à jour vers matplotlib 1.1.1, il ressemble à la plt.plot(x, y), avec y comme liste de listes (comme fourni par l'auteur de la question), ne travailler plus. La seule étape de traçage sans itération sur les tableaux y est toujours possible après avoir passé y comme numpy.array (En supposant que (numpy) [http://numpy.scipy.org/] a été précédemment importé).

Dans ce cas, utilisez plt.plot(x, y) (si les données du tableau 2D y sont organisées en colonnes [axe 1]) ou plt.plot(x, y.transpose()) (si les données du tableau y 2D sont organisées comme lignes [axe 0])

Edit 2: comme indiqué par @pelson (voir le commentaire ci-dessous), la fonction iter est inutile et une simple plt.legend(lineObjects, ('foo', 'bar', 'baz')) fonctionne parfaitement

46
gcalmettes

Je suis tombé sur le même problème et maintenant j'ai trouvé la solution la plus simple! J'espère que ce n'est pas trop tard pour vous. Pas d'itérateur, affectez simplement votre résultat à une structure ...

from numpy import *
from matplotlib.pyplot import *
from numpy.random import *

a = Rand(4,4)
a
>>> array([[ 0.33562406,  0.96967617,  0.69730654,  0.46542408],
   [ 0.85707323,  0.37398595,  0.82455736,  0.72127002],
   [ 0.19530943,  0.4376796 ,  0.62653007,  0.77490795],
   [ 0.97362944,  0.42720348,  0.45379479,  0.75714877]])

[b,c,d,e] = plot(a)
legend([b,c,d,e], ["b","c","d","e"], loc=1)
show()

Ressemble à ça: enter image description here

29
Milla Well

Vous pouvez donner les étiquettes tout en traçant les courbes

import pylab as plt

x = [0, 1, 2, 3, 4]
y = [ [0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [9, 8, 7, 6, 5] ]
labels=['foo', 'bar', 'baz']
colors=['r','g','b']

# loop over data, labels and colors
for i in range(len(y)):
    plt.plot(x,y[i],'o-',color=colors[i],label=labels[i])

plt.legend()
plt.show()

enter image description here

4
imsc

En cas de tracé de matrice numpy, attribuez plusieurs légendes à la fois pour chaque colonne

Je voudrais répondre à cette question en traçant une matrice à deux colonnes.

Supposons que vous ayez une matrice à 2 colonnes Ret

alors on peut utiliser ce code pour attribuer plusieurs étiquettes à la fois

import pandas as pd, numpy as np, matplotlib.pyplot as plt
pd.DataFrame(Ret).plot()

plt.xlabel('time')
plt.ylabel('Return')
plt.legend(['Bond Ret','Equity Ret'], loc=0)
plt.show()

J'espère que ça aide

1
rsc05