web-dev-qa-db-fra.com

Comment les paramètres 'c' et 'cmap' se comportent-ils dans un nuage de points matplotlib?

Pour la fonction pyplot.scatter (x, y, s, c ....), 

La documentation de matplotlib indique que: 

c: couleur, séquence ou séquence de couleur, facultatif, par défaut: 'b' Le couleur du marqueur. Valeurs possibles:

Une chaîne de format de couleur unique. Une séquence de spécifications de couleur de longueur n. Une séquence de n nombres à mapper sur des couleurs à l'aide de cmap et la norme. Tableau 2D dans lequel les lignes sont RGB ou RGBA. Notez que c ne devrait pas être une seule séquence numérique RVB ou RGBA, car il s’agit de impossible à distinguer d'un tableau de valeurs à coloraper. Si vous voulez spécifier la même valeur RVB ou RGBA pour tous les points, utilisez un 2D tableau avec une seule ligne.

Cependant, je ne comprends pas comment je peux changer les couleurs des points de données comme je le souhaite}

J'ai ce morceau de code:

import matplotlib.pyplot as plt
import numpy as np
import sklearn
import sklearn.datasets
import sklearn.linear_model
import matplotlib


%matplotlib inline
matplotlib.rcParams['figure.figsize'] = (13.0, 9.0)

# Generate a dataset and plot it
np.random.seed(0)
X, y = sklearn.datasets.make_moons(200, noise=0.55)
print(y)
plt.scatter(X[:,0], X[:,1], c=y)#, cmap=plt.cm.Spectral)

le tracé de sortie

Comment puis-je changer les couleurs pour supposer des points de données noir et vert si je le souhaite? ou autre chose ? Veuillez également expliquer ce que fait exactement la cmap.

Pourquoi mes parcelles sont magenta et bleues chaque fois que j'utilise plt.cm.Spectral?

4
user9999114

Il existe essentiellement deux options pour colorier les points de dispersion.

1. Cartographie externe

Vous pouvez mapper de manière externe des valeurs sur des couleurs et fournir une liste/un tableau de ces couleurs à l'argument de scatter's c.

z = np.array([1,0,1,0,1])
colors = np.array(["black", "green"])
plt.scatter(x,y, c=colors[z])

2. Cartographie interne

Outre les couleurs explicites, il est également possible de fournir une liste/un tableau de valeurs qui doivent être mappées en couleurs conformément à une normalisation et à une palette de couleurs. 

  • colormap est un appelable qui prend en entrée des valeurs flottantes comprises entre 0. et 1. et qui renvoie une couleur RVB.
  • Une normalisation est un appelable qui prend un nombre en entrée et en génère un autre, en fonction de limites définies précédemment. Le cas habituel de Normalize fournirait un mappage linéaire des valeurs comprises entre vmin et vmax et compris entre 0. et 1..

Le moyen naturel d’obtenir une couleur à partir de certaines données est donc de lier les deux, 

cmap = plt.cm.Spectral
norm = plt.Normalize(vmin=4, vmax=5)
z = np.array([4,4,5,4,5])
plt.scatter(x,y, c = cmap(norm(z)))

Ici, la valeur de 4 serait mappée à 0 par la normalisation, et la valeur de 5 serait mappée à 1, de sorte que la palette de couleurs fournisse les deux couleurs les plus à l'extérieur.

Ce processus a lieu en interne dans scatter si un tableau de valeurs numériques est fourni à c.

Une scatter crée une PathCollection, dans laquelle les sous-classes ScalarMappable. Une ScalarMappable consiste en une palette de couleurs, une normalisation et un tableau de valeurs. Par conséquent, ce qui précède est internalisé via

plt.scatter(x,y, c=z, norm=norm, cmap=cmap)

Si les données minimum et maximum doivent être utilisées comme limites pour la normalisation, vous pouvez laisser cet argument de côté.

plt.scatter(x,y, c=z, cmap=cmap)

C'est la raison pour laquelle le résultat de la question sera toujours constitué de points violet et jaune, indépendamment des valeurs fournies à c.

Pour revenir à l'exigence de mapper un tableau de 0 et 1 en noir et vert, vous pouvez maintenant regarder les colormaps fournies par matplotlib et rechercher une palette de couleurs comprenant du noir et du vert. Par exemple. la palette de couleurs nipy_spectral

 enter image description here

Ici, le noir est au début de la palette de couleurs et le vert quelque part au milieu, par exemple à 0.5. Il faudrait donc définir vmin à 0 et vmax, de sorte que vmax*0.5 = 1 (avec 1 la valeur à mapper au vert), c’est-à-dire vmax = 1./0.5 == 2.

import matplotlib.pyplot as plt
import numpy as np
x,y = np.random.Rand(2,6)
z = np.array([0,0,1,1,0,1])

plt.scatter(x,y, c = z, 
            norm = plt.Normalize(vmin=0, vmax=2),
            cmap = "nipy_spectral")

plt.show()

 enter image description here

Comme il peut ne pas y avoir de palette de couleurs avec les couleurs souhaitées disponibles et qu'il peut ne pas être simple d'obtenir les positions de couleur à partir des cartes de couleurs existantes, une alternative consiste à créer une nouvelle carte de couleurs spécifiquement pour l'objectif recherché.

Ici, nous pourrions simplement créer une palette de couleurs de deux couleurs noir et vert. 

matplotlib.colors.ListedColormap(["black", "green"])

Nous n’aurions pas besoin de normalisation ici, car nous n’avons que deux valeurs et pouvons donc compter sur une normalisation automatique.

import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
x,y = np.random.Rand(2,6)
z = np.array([0,0,1,1,0,1])

plt.scatter(x,y, c = z, cmap = mcolors.ListedColormap(["black", "green"]))

plt.show()

 enter image description here

6

Premièrement, pour définir les couleurs en fonction des valeurs dans y, vous pouvez procéder comme suit:

color = ['red' if i==0  else 'green' for i in y]
plt.scatter(X[:,0], X[:,1], c=color)

Parlons maintenant de scatter() et cmap.

Les ColorMaps sont utilisés pour fournir des couleurs à partir de valeurs flottantes. Voir cette documentation pour référence sur les tables de couleurs

 enter image description here

Pour les valeurs comprises entre 0 et 1, une couleur est choisie parmi ces tables de couleurs. 

Par exemple:

plt.cm.Spectral(0.0)
# (0.6196078431372549, 0.00392156862745098, 0.25882352941176473, 1.0) #<== Magenta

plt.cm.Spectral(1.0)
# (0.3686274509803922, 0.30980392156862746, 0.6352941176470588, 1.0) #<== blue

plt.cm.Spectral(1)
# (0.6280661284121491, 0.013302575932333718, 0.26082276047673975, 1.0)

Notez que les résultats de 1.0 et 1 sont différents dans le code ci-dessus, car les entiers et flottants sont gérés différemment, comme indiqué dans la documentation de __call__() here :

Pour les floats, X doit être dans l’intervalle [0.0, 1.0] pour renvoyer le RGBA valeur X*100 pourcent le long de la ligne de palette de couleurs.

Pour les entiers, X doit être compris dans l'intervalle [0, Colormap.N) à Renvoie les valeurs RGBA indexed de la palette de couleurs avec index X.

Veuillez regarder cette réponse pour une meilleure explication sur les cartes de couleurs: -

Dans votre y, vous avez 0 et 1, donc les valeurs RGBA indiquées dans le code ci-dessus sont utilisées (qui représentent deux extrémités de la palette de couleurs spectrale).

Maintenant, voici comment les paramètres c et cmap dans plt.scatter() interagissent.

 _______________________________________________________________________
|No | type of x, y |  c type  | values in c |       result              |
|___|______________|__________|_____________|___________________________|
|1  |   single     |  scalar  |   numbers   | cmap(0.0), no matter      |
|   |    point     |          |             |  what the value in c      |
|___|______________|__________|_____________|___________________________|
|2  |   array of   |  array   |   numbers   | normalize the values in c,|                
|   |    points    |          |             | cmap(normalized val in c) |
|___|______________|__________|_____________|___________________________|
|3  | scalar or    | scalar or| RGBA Values,|  no use of cmap,          |
|   |  array       |  array   |Color Strings|  use colors from c        |
|___|______________|__________|_____________|___________________________|

Une fois que les couleurs réelles sont finalisées, faites défiler les couleurs pour chaque point dans x, y. Si la taille de x, y est égale ou inférieure à la taille des couleurs de c, vous obtenez un mappage parfait, sinon des couleurs plus anciennes sont réutilisées.

Voici un exemple pour illustrer ceci:

# Case 1 from above table

# All three points get the same color = plt.cm.Spectral(0)
plt.scatter(x=0.0, y=0.2, c=0, cmap=plt.cm.Spectral)
plt.scatter(x=0.0, y=0.3, c=1, cmap=plt.cm.Spectral)
plt.scatter(x=0.0, y=0.4, c=1.0, cmap=plt.cm.Spectral)

# Case 2 from above table

# The values in c are normalized 
# highest value in c gets plt.cm.Spectral(1.0)
# lowest value in c gets plt.cm.Spectral(0.0)
# Others in between as per normalizing
# Size of arrays in x, y, and c must match here, else error is thrown
plt.scatter([0.1, 0.1, 0.1, 0.1, 0.1], [0.2, 0.3, 0.4, 0.5, 0.6], 
            c=[1, 2, 3, 4, 5], cmap=plt.cm.Spectral)


# Case 3 from above table => No use of cmap here,
#  blue is assigned to the point
plt.scatter(x=0.2, y=0.3, c='b')

# You can also provide rgba Tuple
plt.scatter(x=0.2, y=0.4, c=plt.cm.Spectral(0.0))

# Since a single point is present, the first color (green) is given
plt.scatter(x=0.2, y=0.5, c=['g', 'r'])

# Same color 'cyan' is assigned to all values
plt.scatter([0.3, 0.3, 0.3, 0.3, 0.3], [0.2, 0.3, 0.4, 0.5, 0.6], 
            c='c')

# Colors are cycled through points
# 4th point will get again first color
plt.scatter([0.4, 0.4, 0.4, 0.4, 0.4], [0.2, 0.3, 0.4, 0.5, 0.6], 
            c=['m', 'y', 'k'])

# Same way for rgba values
# Third point will get first color again
plt.scatter([0.5, 0.5, 0.5, 0.5, 0.5], [0.2, 0.3, 0.4, 0.5, 0.6], 
            c=[plt.cm.Spectral(0.0), plt.cm.Spectral(1.0)])

Sortie:

 enter image description here

Passez en revue les commentaires dans le code et l'emplacement des points ainsi que les couleurs pour bien comprendre. 

Vous pouvez également remplacer le paramètre c par color dans le code du cas 3 et les résultats seront toujours les mêmes.

1
Vivek Kumar