Contexte
J'ai quelques points
points = np.random.uniform(0,10, size = (10,2))
# array([[ 7.35906037, 6.50049804],
[ 3.21883403, 3.81452312],
[ 3.52107154, 1.68233797],
[ 1.47699577, 6.01692348],
[ 3.76051589, 0.25213394],
[ 8.93701081, 5.20377479],
[ 6.5347188 , 2.12940006],
[ 3.62550069, 5.80619507],
[ 1.33393325, 5.0088937 ],
[ 6.99034593, 7.40277623]])
et ils sont "classés" ou étiquetés. Cela signifie que j'ai une liste
labels = np.random.randint(0,3, size = 10)
# array([2, 0, 1, 2, 2, 1, 1, 0, 1, 2])
qui représente les étiquettes (dans l'ordre) de chaque point dans points
.
J'ai aussi quelques points supplémentaires
extraPoints = np.random.uniform(0,10, size = (3,2))
# array([[ 1.91211141, 3.71208978],
# [ 8.10463536, 1.88948511],
# [ 9.79796593, 3.39432552]])
fondamentalement, chacun de ces points détermine l'étiquette de classe. Peu importe COMMENT il a déterminé l'étiquette. Mais tout ce que vous devez savoir, c'est que chacun de ces points supplémentaires est associé à une et une seule étiquette. Il y a donc un nombre égal de points supplémentaires et de possibilités d'étiquettes.
problème
Je veux faire un nuage de points. Je veux attribuer une couleur différente à chaque point dans extraPoints
, et donc cette couleur sera la correspondance pour chaque classe. Cela signifie essentiellement que extraPoints[0]
Est associé à la classe 0
, extraPoints[1]
Est associé à la classe 1
Et extraPoints[2]
Est associé à la classe 2
.
De plus, je veux disperser les points dans points
. N'oubliez pas que chaque point dans points
est associé à l'étiquette correspondante dans labels
. Par exemple, [ 7.35906037, 6.50049804]
Est dans la classe 2
Et a donc la même couleur que extraPoints[2] = [ 9.79796593, 3.39432552]
. De même, le point [ 3.21883403, 3.81452312]
Dans points
est associé à la classe 0
Dans labels
et a donc la même couleur que extraPoints[0] = [ 1.91211141, 3.71208978]
Mon essai
J'ai essayé d'utiliser l'argument c
dans plt.scatter()
mais je ne comprends pas vraiment comment cela fonctionne, et parfois cela fonctionne, parfois il dit "Argument RGBA non valide 0.0" mais semble être arbitraire..
Notez que pour distinguer points
de extraPoints
, je ferai extraPoints
plus grand et avec plus de transparence.
import matplotlib.pyplot as plt
# I scatter the points, and assign c to labels. So hopefully each
# point that ends up in the same label will have the same
# color? I think this part is fine, although I am not sure
plt.scatter(points[:,0], points[:,1], c = labels)
plt.scatter(extraPoints[:,0], extraPoints[:,1], s = 100, alpha = 0.3, c = np.arange(len(extraPoints)))
Comme vous pouvez le constater par vous-même, pour différentes exécutions (puisque chaque fois que nous avons des tableaux aléatoires), nous pouvons soit faire les choses correctement (ou presque), soit obtenir l'erreur dans le titre. Pourquoi cela arrive-t-il?
Extra -pour les braves
Dans ce contexte, imaginez que j'avais aussi quelques valeurs
values = np.random.uniform(0,50, size = 3)
# array([ 14.63459424, 37.41573654, 34.45202082])
J'ai le même nombre de valeurs que j'ai des types d'étiquettes et d'extraPoints (c'est-à-dire 3 dans ce cas). Maintenant, chacun d'eux est associé aux extraPoints correspondants. Ainsi, la première valeur du premier extraPoint et ainsi de suite ..
Je voudrais faire l'intrigue ci-dessus, mais les couleurs auront un "dégradé" qui devient, par exemple, plus clair pour les petites valeurs et plus sombre pour les plus grandes valeurs (ou l'inverse). Comment puis je faire ça? J'ai lu sur les cartes de couleurs, mais je ne peux pas tout à fait l'intégrer à mon problème.
Exemple
Par exemple pour les valeurs ci-dessus, on obtient:
Comme vous pouvez le voir, je n'ai aucun contrôle sur les couleurs. Non seulement cela, mais je n'ai aucune idée de quel point se trouve dans quelle classe (sauf si je reviens en arrière et regarde manuellement chaque point, mais évidemment je ne veux pas cela). C'est pourquoi (et d'autres raisons que je ne couvrirai pas ici), je veux les colorer en fonction d'une valeur dans values
. Plus précisément, je voudrais, disons, avoir une plage de valeurs [10, 20 30]
Qui peut guider la couleur de mes points, afin que je sache quelle classe est "la plus forte"
Premier problème : le code ne s'exécute pas, puisque np.random.uniform(0,10, size = 3)
donne un tableau 1D, alors que vous vous attendez plus tard à ce qu'il soit 2D (extraPoints[:,0]
).
Deuxième problème : labels
peut avoir entre 1 et 3 entrées uniques, donc np.unique(labels)
peut avoir une longueur de 1 à 3 (par exemple labels
peut être tous des zéros, tels que np.unique(labels) == [0]
) de sorte que vous avez plus de points que de couleurs. Cependant c
attend soit un argument de couleur unique soit une liste de valeurs de même longueur que les coordonnées d'entrée.
Troisième problème : Si vous fournissez une liste ou un tableau de longueur 3 ou 4, il n'est pas clair s'il doit s'agir d'une seule couleur RGB ou RGBA ou d'une liste des valeurs à la palette de couleurs. Si vous rencontrez réellement ce problème ou non, cela ne peut être dit avec certitude jusqu'à ce que vous ayez résolu le premier et le deuxième problème.
Mise à jour: une fois les deux premiers problèmes résolus, vous cherchez probablement une barre de couleurs et une palette de couleurs utiles.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
points = np.random.uniform(0,10, size = (10,2))
labels = np.random.randint(0,3, size = 10)
extraPoints = np.random.uniform(0,10, size = (3,2))
sc = plt.scatter(points[:,0], points[:,1], c = labels)
sc2 = plt.scatter(extraPoints[:,0], extraPoints[:,1], s = 144, alpha = 0.7,
c = np.arange(len(extraPoints)))
plt.colorbar(sc)
plt.show()
Ou, si vous souhaitez avoir des couleurs individuelles:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
points = np.random.uniform(0,10, size = (10,2))
labels = np.random.randint(0,3, size = 10)
extraPoints = np.random.uniform(0,10, size = (3,2))
colors=["red", "gold", "limegreen"]
cmap = matplotlib.colors.ListedColormap(colors)
sc = plt.scatter(points[:,0], points[:,1], c = labels, cmap=cmap, vmin=-0.5,vmax=2.5 )
sc2 = plt.scatter(extraPoints[:,0], extraPoints[:,1], s = 144, alpha = 0.7,
c = np.arange(len(extraPoints)), cmap=cmap, vmin=-0.5,vmax=2.5)
plt.colorbar(sc, ticks=np.arange(len(extraPoints)))
plt.show()
Grâce à ImportanceOfBeingErnest, j'ai réussi à résoudre le problème. Je sais que mon explication était vraiment mauvaise, mais ici je la poste pour quelqu'un qui pourrait trouver le même problème à l'avenir:
solution ImportanceOfBeingErnest
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
points = np.random.uniform(0,10, size = (10,2))
labels = np.random.randint(0,3, size = 10)
extraPoints = np.random.uniform(0,10, size = (3,2))
colors=["red", "gold", "limegreen"]
cmap = matplotlib.colors.ListedColormap(colors)
sc = plt.scatter(points[:,0], points[:,1], c = labels, cmap=cmap, vmin=-0.5,vmax=2.5 )
sc2 = plt.scatter(extraPoints[:,0], extraPoints[:,1], s = 144, alpha = 0.7,
c = np.arange(len(extraPoints)), cmap=cmap, vmin=-0.5,vmax=2.5)
plt.colorbar(sc, ticks=np.arange(len(extraPoints)))
plt.show()
Mon complément qui fait ce que je veux
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
points = np.random.uniform(0,10, size = (10,2))
labels = np.random.randint(0,3, size = 10)
extraPoints = np.random.uniform(0,10, size = (3,2))
# CREATE VALUES
values = np.random.uniform(0,50, size=3)
colors=["red", "gold", "limegreen"]
cmap = matplotlib.colors.ListedColormap(colors)
sc = plt.scatter(points[:,0], points[:,1], c = np.array([values[j] for j in labels]), cmap=cmap, vmin=-0.5,vmax=2.5 )
sc2 = plt.scatter(extraPoints[:,0], extraPoints[:,1], s = 144, alpha = 0.7,
c = values, cmap=cmap, vmin=-0.5,vmax=2.5)
plt.colorbar(sc, ticks=np.arange(len(extraPoints)))
plt.show()
La différence est que les couleurs dans sc
sont désormais déterminées par les valeurs dans values
dans le même ordre que labels
, et en même temps, les points dans extraPoints
sont colorés avec la force et l'ordre des valeurs dans values
.