Como escolher uma nova cor para cada linha traçada dentro de uma figura no matplotlib?

109

Gostaria de NÃO especificar uma cor para cada linha traçada e fazer com que cada linha obtivesse uma cor distinta. Mas se eu correr:

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

plt.show()

então recebo esta saída:

Imagem da saída do gráfico pelo código acima

Se você olhar para a imagem acima, você pode ver que matplotlib tenta escolher cores para cada linha que são diferentes, mas eventualmente ele reutiliza cores - as dez primeiras linhas usam as mesmas cores que as dez últimas. Eu só quero impedir que ele repita as cores já usadas E / OU alimentá-lo com uma lista de cores para usar.

Dlamotte
fonte

Respostas:

59

matplotlib 1.5+

Você pode usar axes.set_prop_cycle( exemplo ).

matplotlib 1.0-1.4

Você pode usar axes.set_color_cycle( exemplo ).

matplotlib 0.x

Você pode usar Axes.set_default_color_cycle.

tom10
fonte
1
Mais na linha do que eu estava procurando ... Alguma chance de você adicionar informações sobre como usar um mapa de cores para gerar uma lista de N cores?
dlamotte de
19
@xyld - Sem querer exagerar na minha própria resposta, mas há um exemplo no final desta resposta: stackoverflow.com/questions/4805048/… Basicamente, você apenas faz isso :, [colormap(i) for i in np.linspace(0, 0.9, num_plots)]onde colormapestá um dos mapas de cores matplotlib.pyplot.cme numplotsé o número de cores exclusivas que você deseja. Esteja ciente de que isso pode resultar em cores difíceis de distinguir umas das outras !!
Joe Kington
4
Boa resposta, Joe, e parece responder à pergunta de xyld, então vou deixar assim. Além disso, é importante notar que há algumas boas respostas para a pergunta sobre a geração de cores distintas, como stackoverflow.com/questions/470690/…
tom10
Isso funciona para qualquer enredo? Eu tentei set_prop_cycle no Axes3D, então usei o loop para múltiplos plots com ax.plot_wireframe (), mas 2 plots são coloridos com a mesma cor.
Joonho Park
112

Eu costumo usar o segundo destes:

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)

Exemplo de 2: exemplo de plotagem com iter, próxima cor

Mark Amery
fonte
Usei # 2. Tenho uma lista de canais que preciso traçar, mas eles podem ter durações variadas. Achei que definir n = len dessa lista foi muito útil para ter certeza de que as cores escolhidas abrangem o intervalo e você pode notar a diferença. Se esse número for muito alto, é difícil ver a diferença nas cores.
lilás
Eu usei # 1, foi útil usar com enumerar (list_name)
DevX
11

prop_cycle

color_cyclefoi descontinuado em 1.5 em favor desta generalização: 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()

Também mostrado no exemplo (agora com nome incorreto): http://matplotlib.org/1.5.1/examples/color/color_cycle_demo.html mencionado em: https://stackoverflow.com/a/4971431/895245

Testado em matplotlib 1.5.1.

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

Não sei se você pode mudar a cor automaticamente, mas você pode explorar seu loop para gerar cores diferentes:

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

Nesse caso, as cores variam de preto a 100% verde, mas você pode ajustá-lo se quiser.

Veja a documentação matplotlib plot () e procure o colorargumento de palavra - chave.

Se você quiser alimentar uma lista de cores, apenas certifique-se de que tem uma lista grande o suficiente e então use o índice do loop para selecionar a cor

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

for i in range(20):
   ax1.plot(x, y, color = colors[i])
Andrea Spadaccini
fonte
1
Sim, eu meio que queria evitar fazer algo assim. Eu pesquisei mapas de cores, mas estou um tanto confuso sobre como usá-los.
dlamotte de
Esta solução não produz uma maneira fácil de controlar um mapa de cores
Ryszard Cetnarski
Isso é muito bom, especialmente quando set_prop_cycle falha. Não sei por que set_prop_cycle ou coloração automática falha em plot_wireframe () em Axes3D. Mas este é um tipo de solução básica / manual para colorir.
Joonho Park
6

Você pode usar um "mapa de cores qualitativo" 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)

Testado em matplotlib 3.0.3. Consulte https://github.com/matplotlib/matplotlib/issues/10840 para uma discussão sobre por que você não pode ligar axes.set_prop_cycle(color=cmap).

Uma lista de mapas de cores qualitativos predefinidos está disponível em https://matplotlib.org/gallery/color/colormap_reference.html :

Lista de mapas de cores qualitativos

nyanpasu64
fonte
Observe que leva as primeiras 3 cores em sequência nestes
Ben Jones
2

Você também pode alterar o ciclo de cores padrão em seu matplotlibrcarquivo. Se você não sabe onde está o arquivo, faça o seguinte em python:

import matplotlib
matplotlib.matplotlib_fname()

Isso mostrará o caminho para o arquivo matplotlibrc usado atualmente. Nesse arquivo você encontrará, entre muitas outras configurações, também aquela para axes.color.cycle. Basta inserir a sequência de cores desejada e você a encontrará em cada plotagem que fizer. Observe que você também pode usar todos os nomes de cores html válidos em matplotlib.

Thomasillo
fonte
0

Como notas de resposta de Ciro , você pode usar prop_cyclepara definir uma lista de cores para matplotlib percorrer. Mas quantas cores? E se você quiser usar o mesmo ciclo de cores para muitos plotagens, com diferentes números de linhas?

Uma tática seria usar uma fórmula como a de https://gamedev.stackexchange.com/a/46469/22397 , para gerar uma sequência infinita de cores onde cada cor tenta ser significativamente diferente de todas as que a precederam.

Infelizmente, prop_cyclenão aceita sequências infinitas - ficará pendurado para sempre se você passar por uma. Mas podemos pegar, digamos, as primeiras 1000 cores geradas a partir de tal sequência e defini-la como o ciclo de cores. Dessa forma, para plotagens com qualquer número razoável de linhas, você deve obter cores distintas.

Exemplo:

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

Resultado:

Saída do gráfico pelo código acima

Agora, todas as cores são diferentes - embora eu admita que tenho dificuldade em distinguir algumas delas!

Mark Amery
fonte