¿Cómo elegir un nuevo color para cada línea trazada dentro de una figura en matplotlib?

109

Me gustaría NO especificar un color para cada línea trazada y que cada línea tenga un color distinto. Pero si corro:

from matplotlib import pyplot as plt
for i in range(20):
    plt.plot([0, 1], [i, i])

plt.show()

entonces obtengo esta salida:

Imagen del gráfico generado por el código anterior

Si observa la imagen de arriba, puede ver que matplotlib intenta elegir colores para cada línea que son diferentes, pero eventualmente reutiliza los colores: las diez líneas superiores usan los mismos colores que las diez inferiores. Solo quiero evitar que repita colores ya usados ​​Y / O alimentarlo con una lista de colores para usar.

dlamotte
fuente

Respuestas:

59

matplotlib 1.5+

Puede usar axes.set_prop_cycle( ejemplo ).

matplotlib 1.0-1.4

Puede usar axes.set_color_cycle( ejemplo ).

matplotlib 0.x

Puede utilizar Axes.set_default_color_cycle.

tom10
fuente
1
Más en la línea de lo que estaba buscando ... ¿Alguna posibilidad de que pueda agregar información sobre cómo usar un mapa de colores para generar una lista de N colores?
dlamotte
19
@xyld: no quiero introducir demasiado mi propia respuesta, pero hay un ejemplo al final de esta respuesta: stackoverflow.com/questions/4805048/… Básicamente, solo haces esto:, [colormap(i) for i in np.linspace(0, 0.9, num_plots)]dónde colormapestá uno de los mapas de colores matplotlib.pyplot.cmy numplotses el número de colores únicos que quieras. Sin embargo, tenga en cuenta que esto puede dar como resultado colores que son difíciles de distinguir entre sí.
Joe Kington
4
Buena respuesta Joe, y parece responder a la pregunta de xyld, así que lo dejaré así. Sin embargo, también vale la pena señalar que hay algunas buenas respuestas a preguntas sobre la generación de colores distintos, como stackoverflow.com/questions/470690/…
tom10
¿Funciona para alguna trama? Probé set_prop_cycle en Axes3D, luego usé for loop para múltiples parcelas con ax.plot_wireframe (), pero 2 parcelas están coloreadas con el mismo color.
Joonho Park
112

Normalmente uso el segundo de estos:

from matplotlib.pyplot import cm
import numpy as np

#variable n below should be number of curves to plot

#version 1:

color=cm.rainbow(np.linspace(0,1,n))
for i,c in zip(range(n),color):
   plt.plot(x, y,c=c)

#or version 2:

color=iter(cm.rainbow(np.linspace(0,1,n)))
for i in range(n):
   c=next(color)
   plt.plot(x, y,c=c)

Ejemplo de 2: gráfico de ejemplo con iter, siguiente color

Mark Amery
fuente
Usé el # 2. Tengo una lista de canales que necesito trazar, pero pueden tener distintas longitudes. Descubrí que establecer n = len de esa lista fue muy útil para asegurarme de que los colores elegidos abarquen el rango y puedas notar la diferencia. Si ese número es demasiado alto, es difícil ver la diferencia en los colores.
malva
Usé el n
DevX
11

prop_cycle

color_cyclefue obsoleto en 1.5 a favor de esta generalización: http://matplotlib.org/users/whats_new.html#added-axes-prop-cycle-key-to-rcparams

# cycler is a separate package extracted from matplotlib.
from cycler import cycler
import matplotlib.pyplot as plt

plt.rc('axes', prop_cycle=(cycler('color', ['r', 'g', 'b'])))
plt.plot([1, 2])
plt.plot([2, 3])
plt.plot([3, 4])
plt.plot([4, 5])
plt.plot([5, 6])
plt.show()

También se muestra en el ejemplo (ahora mal nombrado): http://matplotlib.org/1.5.1/examples/color/color_cycle_demo.html mencionado en: https://stackoverflow.com/a/4971431/895245

Probado en matplotlib 1.5.1.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
9

No sé si puede cambiar el color automáticamente, pero podría aprovechar su bucle para generar diferentes colores:

for i in range(20):
   ax1.plot(x, y, color = (0, i / 20.0, 0, 1)

En este caso, los colores variarán del negro al 100% verde, pero puedes afinarlo si quieres.

Consulte los documentos de matplotlib plot () y busque el colorargumento de palabra clave.

Si desea alimentar una lista de colores, solo asegúrese de tener una lista lo suficientemente grande y luego use el índice del ciclo para seleccionar el color

colors = ['r', 'b', ...., 'w']

for i in range(20):
   ax1.plot(x, y, color = colors[i])
Andrea Spadaccini
fuente
1
Sí, quería evitar hacer algo como esto. Miré los mapas de colores, pero estoy bastante confundido sobre cómo usarlos.
dlamotte
Esta solución no produce una manera fácil de controlar un mapa de
colores
Esto es muy bueno, especialmente cuando falla set_prop_cycle. No sé por qué set_prop_cycle o la coloración automática fallan en plot_wireframe () en Axes3D. Pero esta es una especie de solución básica / manual para colorear.
Joonho Park
6

Puede utilizar un "mapa de colores cualitativo" predefinido como este:

from matplotlib.cm import get_cmap

name = "Accent"
cmap = get_cmap(name)  # type: matplotlib.colors.ListedColormap
colors = cmap.colors  # type: list
axes.set_prop_cycle(color=colors)

Probado en matplotlib 3.0.3. Consulte https://github.com/matplotlib/matplotlib/issues/10840 para obtener información sobre por qué no puede llamar axes.set_prop_cycle(color=cmap).

Una lista de mapas de color cualitativos predefinidos está disponible en https://matplotlib.org/gallery/color/colormap_reference.html :

Lista de mapas de color cualitativos

nyanpasu64
fuente
Tenga en cuenta que toma los primeros 3 colores en secuencia en estos
Ben Jones
2

También puede cambiar el ciclo de color predeterminado en su matplotlibrcarchivo. Si no sabe dónde está ese archivo, haga lo siguiente en Python:

import matplotlib
matplotlib.matplotlib_fname()

Esto le mostrará la ruta a su archivo matplotlibrc actualmente utilizado. En ese archivo encontrará, entre muchas otras configuraciones, también la de axes.color.cycle. Simplemente coloque la secuencia de colores deseada y la encontrará en cada trama que haga. Tenga en cuenta que también puede utilizar todos los nombres de colores HTML válidos en matplotlib.

Thomasillo
fuente
0

Como señala la respuesta de Ciro , puede usarprop_cycle para establecer una lista de colores para que matplotlib recorra el ciclo. ¿Pero cuántos colores? ¿Qué sucede si desea utilizar el mismo ciclo de color para muchos gráficos, con diferentes números de líneas?

Una táctica sería utilizar una fórmula como la de https://gamedev.stackexchange.com/a/46469/22397 , para generar una secuencia infinita de colores donde cada color intenta ser significativamente diferente de todos los que lo precedieron.

Desafortunadamente, prop_cycleno aceptará secuencias infinitas, se bloqueará para siempre si le pasa una. Pero podemos tomar, digamos, los primeros 1000 colores generados a partir de dicha secuencia y establecerlo como ciclo de color. De esa manera, para las parcelas con cualquier número de líneas, debería obtener colores distinguibles.

Ejemplo:

from matplotlib import pyplot as plt
from matplotlib.colors import hsv_to_rgb
from cycler import cycler

# 1000 distinct colors:
colors = [hsv_to_rgb([(i * 0.618033988749895) % 1.0, 1, 1])
          for i in range(1000)]
plt.rc('axes', prop_cycle=(cycler('color', colors)))

for i in range(20):
    plt.plot([1, 0], [i, i])

plt.show()

Salida:

Grafica la salida por el código anterior

Ahora, todos los colores son diferentes, ¡aunque admito que me cuesta distinguir algunos de ellos!

Mark Amery
fuente