¿Cómo generar colores aleatorios en matplotlib?

¿Cuál es el ejemplo trivial de cómo generar colores aleatorios para pasar a funciones de trazado?

Estoy llamando a dispersar dentro de un bucle y quiero que cada plot tenga un color diferente.

for X,Y in data: scatter(X, Y, c=??) 

c: un color. c puede ser una cadena de formato de un solo color, o una secuencia de especificaciones de color de longitud N, o una secuencia de N números que deben asignarse a los colores utilizando el cmap y la norma especificada a través de kwargs (ver más abajo). Tenga en cuenta que c no debe ser una única secuencia RGB o RGBA numérica porque no se puede distinguir de una matriz de valores para ser asignados en color. c puede ser una matriz 2-D en la que las filas son RGB o RGBA, sin embargo.

 for X,Y in data: scatter(X, Y, c=numpy.random.rand(3,1)) 

Estoy llamando a dispersar dentro de un bucle y quiero que cada plot en un color diferente.

Basado en eso, y en su respuesta: me parece que realmente desea n colores distintos para sus conjuntos de datos; desea asignar los índices enteros 0, 1, ..., n-1 a distintos colores RGB. Algo como:

mapeo de índice a color

Aquí está la función para hacerlo:

 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) 

Uso en su fragmento de pseudo- código en la pregunta:

 cmap = get_cmap(len(data)) for i, (X, Y) in enumerate(data): scatter(X, Y, c=cmap(i)) 

Generé la figura en mi respuesta con el siguiente código:

 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() 

Probado con Python 2.7 y matplotlib 1.5, y con Python 3.5 y matplotlib 2.0. Funciona como se esperaba.

elaborando la respuesta de @ john-mee, si tiene datos arbitrariamente largos pero no necesita colores estrictamente únicos:

para python 2:

 from itertools import cycle cycol = cycle('bgrcmk') for X,Y in data: scatter(X, Y, c=cycol.next()) 

para python 3:

 from itertools import cycle cycol = cycle('bgrcmk') for X,Y in data: scatter(X, Y, c=next(cycol)) 

Esto tiene la ventaja de que los colores son fáciles de controlar y que son cortos.

Durante algún tiempo me molestó mucho el hecho de que matplotlib no genera mapas de colores con colores aleatorios, ya que esta es una necesidad común para las tareas de segmentación y agrupación en clústeres.

Con solo generar colores al azar podemos terminar con algunos que son demasiado shinys o demasiado oscuros, lo que dificulta la visualización. Además, generalmente necesitamos que el primer o último color sea negro, que representa el fondo o los valores atípicos. Así que he escrito una pequeña función para mi trabajo diario.

Aquí está el comportamiento de la misma:

 new_cmap = rand_cmap(100, type='bright', first_color_black=True, last_color_black=False, verbose=True) 

Mapa de colores generado

A continuación, utiliza new_cmap como su mapa de colores en matplotlib:

 ax.scatter(X,Y, c=label, cmap=new_cmap, vmin=0, vmax=num_labels) 

El código está aquí:

 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 

También está en github: https://github.com/delestro/rand_cmap

Cuando menos de 9 conjuntos de datos:

 colors = "bgrcmykw" color_index = 0 for X,Y in data: scatter(X,Y, c=colors[color_index]) color_index += 1 

Aquí hay una versión más concisa de la respuesta de Ali que da un color distinto por plot:

 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)) 

Dado que la pregunta es How to generate random colors in matplotlib? y mientras buscaba una respuesta con respecto a las pie plots , creo que vale la pena poner una respuesta aquí (para 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() 

Salida

introduzca la descripción de la imagen aquí

introduzca la descripción de la imagen aquí

Basado en la respuesta de Ali y Champitoad:

Si desea probar diferentes paletas para el mismo, puede hacerlo en unas pocas líneas:

cmap=plt.cm.get_cmap(plt.cm.viridis,143)

^ 143 siendo el número de colores que estás muestreando

Escogí 143 porque aquí entra en juego toda la gama de colores en el mapa de colores. Lo que puede hacer es muestrear el enésimo color en cada iteración para obtener el efecto de mapa de colores.

n=20 for i,(x,y) in enumerate(points): plt.scatter(x,y,c=cmap(n*i))

Mejorando la respuesta https://stackoverflow.com/a/14720445/6654512 para trabajar con Python3. Ese fragmento de código generaría a veces números mayores que 1 y matplotlib arrojaría un error.

 for X,Y in data: scatter(X, Y, c=numpy.random.random(3))