Quel est l'exemple trivial de la génération de couleurs aléatoires pour passer aux fonctions de traçage?
J'appelle scatter dans une boucle et je veux que chaque parcelle ait une couleur différente.
for X,Y in data:
scatter(X, Y, c=??)
c: une couleur. c peut être une chaîne de format de couleur unique, ou une séquence de spécifications de couleur de longueur N, ou une séquence de N nombres à mapper sur des couleurs à l'aide de la cmap et de la norme spécifiées via kwargs (voir ci-dessous). Notez que c ne doit pas être une séquence numérique RVB ou RGBA unique, car il est impossible de la distinguer d’un tableau de valeurs à modéliser. c peut être un tableau 2D dans lequel les lignes sont RVB ou RGBA, cependant.
for X,Y in data:
scatter(X, Y, c=numpy.random.Rand(3,))
J'appelle scatter dans une boucle et je veux que chaque parcelle soit d'une couleur différente.
Sur la base de cela et de votre réponse: il me semble que vous voulez réellement n
des couleurs distinctes pour vos jeux de données; vous voulez mapper les indices entiers 0, 1, ..., n-1
pour distinguer les couleurs RVB. Quelque chose comme:
Voici la fonction pour le faire:
import matplotlib.pyplot as plt
def get_cmap(n, name='hsv'):
'''Returns a function that maps each index in 0, 1, ..., n-1 to a distinct
RGB color; the keyword argument name must be a standard mpl colormap name.'''
return plt.cm.get_cmap(name, n)
Utilisation dans votre pseudo - extrait de code dans la question:
cmap = get_cmap(len(data))
for i, (X, Y) in enumerate(data):
scatter(X, Y, c=cmap(i))
J'ai généré le chiffre dans ma réponse avec le code suivant:
import matplotlib.pyplot as plt
def get_cmap(n, name='hsv'):
'''Returns a function that maps each index in 0, 1, ..., n-1 to a distinct
RGB color; the keyword argument name must be a standard mpl colormap name.'''
return plt.cm.get_cmap(name, n)
def main():
N = 30
fig=plt.figure()
ax=fig.add_subplot(111)
plt.axis('scaled')
ax.set_xlim([ 0, N])
ax.set_ylim([-0.5, 0.5])
cmap = get_cmap(N)
for i in range(N):
rect = plt.Rectangle((i, -0.5), 1, 1, facecolor=cmap(i))
ax.add_artist(rect)
ax.set_yticks([])
plt.show()
if __name__=='__main__':
main()
Testé avec les deux Python 2.7 & matplotlib 1.5, et avec Python 3.5 & matplotlib 2.0. Il fonctionne comme prévu.
en élaborant la réponse de @ john-mee, si vous avez des données arbitrairement longues mais que vous n’avez pas besoin de couleurs strictement uniques:
pour python 2:
from itertools import cycle
cycol = cycle('bgrcmk')
for X,Y in data:
scatter(X, Y, c=cycol.next())
pour python 3:
from itertools import cycle
cycol = cycle('bgrcmk')
for X,Y in data:
scatter(X, Y, c=next(cycol))
cela a l'avantage que les couleurs sont faciles à contrôler et que c'est court.
Pendant un certain temps, le fait que matplotlib ne génère pas de mappes de couleurs avec des couleurs aléatoires m'ennuyait beaucoup, car il s'agit d'un besoin courant pour les tâches de segmentation et de mise en cluster.
En générant simplement des couleurs aléatoires, nous pouvons en arriver à des couleurs trop claires ou trop sombres, ce qui rend la visualisation difficile. En outre, nous avons généralement besoin que la première ou la dernière couleur soit noire, représentant l’arrière-plan ou les valeurs éloignées. J'ai donc écrit une petite fonction pour mon travail quotidien
Voici le comportement de celui-ci:
new_cmap = Rand_cmap(100, type='bright', first_color_black=True, last_color_black=False, verbose=True)
Alors vous utilisez simplement new_cmap comme palette de couleurs sur matplotlib:
ax.scatter(X,Y, c=label, cmap=new_cmap, vmin=0, vmax=num_labels)
Le code est ici:
def Rand_cmap(nlabels, type='bright', first_color_black=True, last_color_black=False, verbose=True):
"""
Creates a random colormap to be used together with matplotlib. Useful for segmentation tasks
:param nlabels: Number of labels (size of colormap)
:param type: 'bright' for strong colors, 'soft' for pastel colors
:param first_color_black: Option to use first color as black, True or False
:param last_color_black: Option to use last color as black, True or False
:param verbose: Prints the number of labels and shows the colormap. True or False
:return: colormap for matplotlib
"""
from matplotlib.colors import LinearSegmentedColormap
import colorsys
import numpy as np
if type not in ('bright', 'soft'):
print ('Please choose "bright" or "soft" for type')
return
if verbose:
print('Number of labels: ' + str(nlabels))
# Generate color map for bright colors, based on hsv
if type == 'bright':
randHSVcolors = [(np.random.uniform(low=0.0, high=1),
np.random.uniform(low=0.2, high=1),
np.random.uniform(low=0.9, high=1)) for i in xrange(nlabels)]
# Convert HSV list to RGB
randRGBcolors = []
for HSVcolor in randHSVcolors:
randRGBcolors.append(colorsys.hsv_to_rgb(HSVcolor[0], HSVcolor[1], HSVcolor[2]))
if first_color_black:
randRGBcolors[0] = [0, 0, 0]
if last_color_black:
randRGBcolors[-1] = [0, 0, 0]
random_colormap = LinearSegmentedColormap.from_list('new_map', randRGBcolors, N=nlabels)
# Generate soft pastel colors, by limiting the RGB spectrum
if type == 'soft':
low = 0.6
high = 0.95
randRGBcolors = [(np.random.uniform(low=low, high=high),
np.random.uniform(low=low, high=high),
np.random.uniform(low=low, high=high)) for i in xrange(nlabels)]
if first_color_black:
randRGBcolors[0] = [0, 0, 0]
if last_color_black:
randRGBcolors[-1] = [0, 0, 0]
random_colormap = LinearSegmentedColormap.from_list('new_map', randRGBcolors, N=nlabels)
# Display colorbar
if verbose:
from matplotlib import colors, colorbar
from matplotlib import pyplot as plt
fig, ax = plt.subplots(1, 1, figsize=(15, 0.5))
bounds = np.linspace(0, nlabels, nlabels + 1)
norm = colors.BoundaryNorm(bounds, nlabels)
cb = colorbar.ColorbarBase(ax, cmap=random_colormap, norm=norm, spacing='proportional', ticks=None,
boundaries=bounds, format='%1i', orientation=u'horizontal')
return random_colormap
C'est aussi sur github: https://github.com/delestro/Rand_cmap
Lorsque moins de 9 jeux de données:
colors = "bgrcmykw"
color_index = 0
for X,Y in data:
scatter(X,Y, c=colors[color_index])
color_index += 1
Puisque la question est How to generate random colors in matplotlib?
et comme je cherchais une réponse concernant pie plots
, Je pense que cela vaut la peine de mettre une réponse ici (pour pies
)
import numpy as np
from random import sample
import matplotlib.pyplot as plt
import matplotlib.colors as pltc
all_colors = [k for k,v in pltc.cnames.items()]
fracs = np.array([600, 179, 154, 139, 126, 1185])
labels = ["label1", "label2", "label3", "label4", "label5", "label6"]
explode = ((fracs == max(fracs)).astype(int) / 20).tolist()
for val in range(2):
colors = sample(all_colors, len(fracs))
plt.figure(figsize=(8,8))
plt.pie(fracs, labels=labels, autopct='%1.1f%%',
shadow=True, explode=explode, colors=colors)
plt.legend(labels, loc=(1.05, 0.7), shadow=True)
plt.show()
Sortie
Voici une version plus concise de la réponse d'ALi donnant une couleur distincte par tracé:
import matplotlib.pyplot as plt
N = len(data)
cmap = plt.cm.get_cmap("hsv", N+1)
for i in range(N):
X,Y = data[i]
plt.scatter(X, Y, c=cmap(i))
Basé sur la réponse de ALi et Champitoad:
Si vous voulez essayer différentes palettes pour la même chose, vous pouvez le faire en quelques lignes:
cmap=plt.cm.get_cmap(plt.cm.viridis,143)
^ 143 étant le nombre de couleurs que vous échantillonnez
J'ai choisi 143 parce que toute la gamme de couleurs de la palette de couleurs entre en jeu ici. Ce que vous pouvez faire est d’échantillonner la nième couleur à chaque itération pour obtenir l’effet de palette de couleurs.
n=20 for i,(x,y) in enumerate(points): plt.scatter(x,y,c=cmap(n*i))
Amélioration de la réponse https://stackoverflow.com/a/14720445/6654512 pour utiliser Python3. Ce code génère parfois des nombres supérieurs à 1 et matplotlib génère une erreur.
for X,Y in data:
scatter(X, Y, c=numpy.random.random(3))
enter code here
import numpy as np
clrs = np.linspace( 0, 1, 18 ) # It will generate
# color only for 18 for more change the number
np.random.shuffle(clrs)
colors = []
for i in range(0, 72, 4):
idx = np.arange( 0, 18, 1 )
np.random.shuffle(idx)
r = clrs[idx[0]]
g = clrs[idx[1]]
b = clrs[idx[2]]
a = clrs[idx[3]]
colors.append([r, g, b, a])