99 votes

Changer la couleur selon les étiquettes de classe

J'ai deux vecteurs, l'un avec des valeurs et l'autre avec des étiquettes de classe comme 1, 2, 3, etc.

J'aimerais tracer tous les points appartenant à la classe 1 en rouge, à la classe 2 en bleu, à la classe 3 en vert, etc. Comment puis-je faire cela ?

108voto

salomonvh Points 71

La réponse acceptée est parfaitement exacte, mais si vous souhaitez spécifier quelle étiquette de classe doit être attribuée à une couleur ou une étiquette spécifique, vous pourriez faire ce qui suit. J'ai fait un peu de gymnastique avec les étiquettes de couleur, mais en faisant le graphique lui-même se réduit à une belle ligne. Cela fonctionne très bien pour tracer les résultats des classifications faites avec sklearn. Chaque étiquette correspond à une coordonnée (x,y).

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

x = [4,8,12,16,1,4,9,16]
y = [1,4,9,16,4,8,12,3]
label = [0,1,2,3,0,1,2,3]
colors = ['red','green','blue','purple']

fig = plt.figure(figsize=(8,8))
plt.scatter(x, y, c=label, cmap=matplotlib.colors.ListedColormap(colors))

cb = plt.colorbar()
loc = np.arange(0,max(label),max(label)/float(len(colors)))
cb.set_ticks(loc)
cb.set_ticklabels(colors)

Scatter plot color labels

En utilisant une version légèrement modifiée de cette réponse, on peut généraliser ce qui précède pour N couleurs comme suit :

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

N = 23 # Nombre d'étiquettes

# Configuration du graphique
fig, ax = plt.subplots(1,1, figsize=(6,6))
# Définition des données
x = np.random.rand(1000)
y = np.random.rand(1000)
tag = np.random.randint(0,N,1000) # Attribuer un tag à chaque point avec une étiquette correspondante

# Définition de la colormap
cmap = plt.cm.jet
# Extraire toutes les couleurs de la carte .jet
cmaplist = [cmap(i) for i in range(cmap.N)]
# Créer la nouvelle carte
cmap = cmap.from_list('Custom cmap', cmaplist, cmap.N)

# Définition des intervalles et normalisation
bounds = np.linspace(0,N,N+1)
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)

# Créer le nuage de points
scat = ax.scatter(x,y,c=tag,s=np.random.randint(100,500,N),cmap=cmap, norm=norm)
# Créer la barre de couleur
cb = plt.colorbar(scat, spacing='proportional',ticks=bounds)
cb.set_label('Custom cbar')
ax.set_title('Mappages de couleurs discrètes')
plt.show()

Ce qui donne :

enter image description here

0 votes

Pouvez-vous le faire avec 23 couleurs (comme l'OP le dit qu'il a, et moi aussi) et, disons, 1k points aléatoires ? Votre réponse est géniale, et j'ai voté positivement pour l'image, mais j'aimerais savoir si cela fonctionne avec plus de 10 classes.

0 votes

Excellente réponse! Beaucoup plus approfondie que la réponse acceptée.

0 votes

Comment généraliser à un ensemble de données non NxN ? c'est-à-dire un nombre différent de lignes et de colonnes

32voto

brentlance Points 901

En supposant que vous avez vos données dans un tableau 2D, cela devrait fonctionner :

import numpy
import pylab
xy = numpy.zeros((2, 1000))
xy[0] = range(1000)
xy[1] = range(1000)
colors = [int(i % 23) for i in xy[0]]
pylab.scatter(xy[0], xy[1], c=colors)
pylab.show()

Vous pouvez également définir un attribut cmap pour contrôler les couleurs qui apparaîtront grâce à l'utilisation d'une carte de couleurs ; c'est-à-dire remplacez la ligne pylab.scatter par :

pylab.scatter(xy[0], xy[1], c=colors, cmap=pylab.cm.cool)

Une liste de cartes de couleurs peut être trouvée ici

0 votes

En réalité, mes données comportent 23 étiquettes de ce type. Ainsi, j'ai attribué le vecteur de couleurs de 0 à 22 sous forme de liste avec une longueur de vecteur identique à xy. Cependant, une erreur survient indiquant que la longueur de la séquence doit être de 3 ou 4.

1 votes

Pouvez-vous ajouter un exemple de code et le message d'erreur à votre question? J'ai modifié l'exemple simple que j'ai placé ici pour avoir mille points et 23 étiquettes.

0 votes

Je ne reçois pas d'erreur lorsque j'utilise la fonction plot. Malheureusement, j'avais écrasé mon code avec la fonction plot et je n'ai donc pas pu reproduire l'erreur.

30voto

Nguyen Points 371

Une solution simple consiste à attribuer une couleur à chaque classe. De cette façon, nous pouvons contrôler la couleur de chaque classe. Par exemple :

arr1 = [1, 2, 3, 4, 5]
arr2 = [2, 3, 3, 4, 4]
labl = [0, 1, 1, 0, 0]
color= ['rouge' if l == 0 else 'vert' for l in labl]
plt.scatter(arr1, arr2, color=color)

0 votes

Je suivais la même approche, mais je ne peux pas attribuer une légende : ajouter plt.legend('A', 'B') n'écrira qu'une seule classe. Pouvez-vous me dire comment afficher les deux ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X