web-dev-qa-db-fra.com

Diagramme de dispersion de Matplotlib avec légende

Je veux créer un nuage de points Matplotlib, avec une légende montrant la couleur de chaque classe. Par exemple, j'ai une liste de valeurs x et y et une liste de valeurs classes. Chaque élément des listes x, y et classes correspond à un point du tracé. Je veux que chaque classe ait sa propre couleur, que j'ai déjà codée, mais je veux ensuite que les classes soient affichées dans une légende. Quels paramètres dois-je passer à la fonction legend() pour y parvenir?

Voici mon code jusqu'à présent:

x = [1, 3, 4, 6, 7, 9]
y = [0, 0, 5, 8, 8, 8]
classes = ['A', 'A', 'B', 'C', 'C', 'C']
colours = ['r', 'r', 'b', 'g', 'g', 'g']
plt.scatter(x, y, c=colours)
22
Karnivaurus

Tout d'abord, j'ai le sentiment que vous vouliez utiliser des apostrophes, pas des contre-coups lors de la déclaration des couleurs.

Pour une légende, vous avez besoin de quelques formes ainsi que des classes. Par exemple, ce qui suit crée une liste de rectangles appelés recs pour chaque couleur dans class_colours.

import matplotlib.patches as mpatches

classes = ['A','B','C']
class_colours = ['r','b','g']
recs = []
for i in range(0,len(class_colours)):
    recs.append(mpatches.Rectangle((0,0),1,1,fc=class_colours[i]))
plt.legend(recs,classes,loc=4)

Output from first code block

Vous pouvez également utiliser des cercles si vous le souhaitez, consultez simplement le matplotlib.patches Documentation. Il existe une deuxième façon de créer une légende, dans laquelle vous spécifiez le "Label" pour un ensemble de points en utilisant une commande de dispersion distincte pour chaque ensemble. Un exemple de ceci est donné ci-dessous.

classes = ['A','A','B','C','C','C']
colours = ['r','r','b','g','g','g']
for (i,cla) in enumerate(set(classes)):
    xc = [p for (j,p) in enumerate(x) if classes[j]==cla]
    yc = [p for (j,p) in enumerate(y) if classes[j]==cla]
    cols = [c for (j,c) in enumerate(colours) if classes[j]==cla]
    plt.scatter(xc,yc,c=cols,label=cla)
plt.legend(loc=4)

enter image description here

La première méthode est celle que j'ai personnellement utilisée, la seconde que je viens de découvrir en consultant la documentation de matplotlib. Comme les légendes couvraient des points de données, je les ai déplacés, et les emplacements des légendes peuvent être trouvés ici . S'il existe un autre moyen de créer une légende, je n'ai pas pu le trouver après quelques recherches rapides dans les documents.

14
TheSchwa

Il y a deux façons de procéder. L'un d'eux vous donne des entrées de légende pour chaque chose que vous tracez, et l'autre vous permet de mettre tout ce que vous voulez dans la légende, en volant lourdement la réponse this .

Voici la première façon:

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-1,1,100)

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

#Plot something
ax.plot(x,x, color='red', ls="-", label="$P_1(x)$")
ax.plot(x,0.5 * (3*x**2-1), color='green', ls="--", label="$P_2(x)$")
ax.plot(x,0.5 * (5*x**3-3*x), color='blue', ls=":", label="$P_3(x)$")

ax.legend()
plt.show()

enter image description here

La fonction ax.legend() a plus d'une utilisation, la première crée simplement la légende basée sur les lignes de l'objet axes, la seconde vous permet de contrôler les entrées manuellement et est décrite ici .

Vous devez essentiellement donner à la légende les poignées de ligne et les étiquettes associées.

L'autre façon vous permet de mettre tout ce que vous voulez dans la légende, en créant les objets et les étiquettes Artist, et en les passant à la fonction ax.legend(). Vous pouvez soit l'utiliser pour ne mettre que certaines de vos lignes dans la légende, soit vous pouvez l'utiliser pour mettre tout ce que vous voulez dans la légende.

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-1,1,100)

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

#Plot something
p1, = ax.plot(x,x, color='red', ls="-", label="$P_1(x)$")
p2, = ax.plot(x,0.5 * (3*x**2-1), color='green', ls="--", label="$P_2(x)$")
p3, = ax.plot(x,0.5 * (5*x**3-3*x), color='blue', ls=":", label="$P_3(x)$")

#Create legend from custom artist/label lists
ax.legend([p1,p2], ["$P_1(x)$", "$P_2(x)$"])

plt.show()

enter image description here

Ou ici, nous créons de nouveaux objets Line2D Et les donnons à la légende.

import matplotlib.pyplot as pltit|delete|flag
import numpy as np
import matplotlib.patches as mpatches

x = np.linspace(-1,1,100)

fig = plt.figure()
ax = fig.add_subplot(1,1,1)

#Plot something
p1, = ax.plot(x,x, color='red', ls="-", label="$P_1(x)$")
p2, = ax.plot(x,0.5 * (3*x**2-1), color='green', ls="--", label="$P_2(x)$")
p3, = ax.plot(x,0.5 * (5*x**3-3*x), color='blue', ls=":", label="$P_3(x)$")

fakeLine1 = plt.Line2D([0,0],[0,1], color='Orange', marker='o', linestyle='-')
fakeLine2 = plt.Line2D([0,0],[0,1], color='Purple', marker='^', linestyle='')
fakeLine3 = plt.Line2D([0,0],[0,1], color='LightBlue', marker='*', linestyle=':')

#Create legend from custom artist/label lists
ax.legend([fakeLine1,fakeLine2,fakeLine3], ["label 1", "label 2", "label 3"])

plt.show()

enter image description here

J'ai également essayé de faire fonctionner la méthode en utilisant patches, comme sur la page de guide de la légende de matplotlib, mais cela ne semblait pas fonctionner, j'ai donc abandonné.

5
will

Ceci est facilement géré dans le nuage de points de Seaborn. En voici une implémentation.

import matplotlib.pyplot as plt
import seaborn as sns

x = [1, 3, 4, 6, 7, 9]
y = [0, 0, 5, 8, 8, 8]
classes = ['A', 'A', 'B', 'C', 'C', 'C']
colours = ['r', 'r', 'b', 'g', 'g', 'g']

sns.scatterplot(x=x, y=y, hue=classes)
plt.show()

plot

3

Dans mon projet, je souhaite également créer une légende de dispersion vide. Voici ma solution:

from mpl_toolkits.basemap import Basemap
#use the scatter function from matplotlib.basemap
#you can use pyplot or other else.
select = plt.scatter([], [],s=200,marker='o',linewidths='3',edgecolor='#0000ff',facecolors='none',label=u'监测站点') 
plt.legend(handles=[select],scatterpoints=1)

Prenez soin de "label", "scatterpoints" ci-dessus.

1
bazingaedward