2015-02-11 3 views
5

Grafico un grafico a linee semplice con matplotlib/pyplot. Nella stessa trama, ci sono fino a 20 linee. Matplotlib sceglie automaticamente un colore di linea. Ho bisogno di disegnare il primo delle linee in un rosso più spesso.Grafico a linee Pyplot/matplotlib - stesso colore

Così ho provato:

if (i==0):      # first line 
    plt.plot(x, y, 'r', lw=2.5) 
else:       # other lines 
    plt.plot(x, y) 

Finora molto semplice. La prima riga è corretta. Ma anche una delle altre linee è rossa. Come può evitare questo?

risposta

11

Il colore mappa predefinita jet va dal blu al rosso. Ogni mappa colori incorporata ha anche una mappa colori sorella con i colori in ordine inverso. La mappa dei colori invertita ha lo stesso nome con il suffisso _r. Pertanto, jet_r passa dal rosso al blu.

in modo da poter dare ad ogni linea un colore unico dal jet_r colormap definendo

color = cmap(float(i)/N) 

dove cmap è il jet_r mappa di colori. La mappa dei colori cmap è una callable. Quando viene passato un float, restituisce una tupla RGB. Quindi, se float(i)/N è un float distinto tra 0 e 1 per ogni riga, ciascuna linea otterrà automaticamente un colore distinto.


Per esempio,

import numpy as np 
import matplotlib.pyplot as plt 

x = np.linspace(0, 5, 100) 
cmap = plt.get_cmap('jet_r') 
N = 20 
for i, n in enumerate(np.linspace(2.0, 0, N)): 
    y = np.sin(x)*x**n 
    color = cmap(float(i)/N) 
    lw = 2.5 if i==0 else 1 
    # zorder controls the order in which the lines are drawn. 
    # The line with the highest zorder lies on top. 
    plt.plot(x, y, c=color, lw=lw, zorder=-i) 
plt.show() 

rendimenti

enter image description here

+0

il lavoro è perfetto per me! – user3265764

1

Ci sono molti modi in cui potreste potenzialmente farlo. Probabilmente il più semplice e più ovvia sarebbe quella di specificare i colori linea separata per tutte le 20 linee:

line_colors = ['r', 'g', 'b', 'c', 'm', 'y', 'k', ...] 

for ii in range(20): 
    plt.plot(x, y, c=line_colors[ii]) 

Naturalmente sarebbe un po 'un dolore di dover digitare le 20 diverse stringhe di colore!

Si potrebbe anche generare i colori disegnando un array di valori RGBA da una mappa dei colori come in risposta di unutbu, ma la maggior parte del built-in mappe di colore rosso contengono, in modo che ci sia bisogno di scegliere una mappa di colori che non lo fa contiene rosso, design your own, oppure scegli un intervallo di valori float tra 0 e 1 che non è stato mappato sulla regione rossa della mappa di colori.

Se non ti dispiace alcuni colori di essere ripetuti, un'opzione potenzialmente più bello sarebbe quella di utilizzare itertools.cycle per creare un oggetto generatore che produce colori in un ciclo ripetitivo:

from itertools import cycle 

color_cycle = cycle(['g', 'b', 'c', 'm', 'y', 'k']) 

for ii in range(20): 
    if ii == 0: 
     plt.plot(x, y, c='r') 
    else: 
     plt.plot(x, y, c=cycle.next()) 

In realtà, questo è esattamente come funziona il ciclo di colori matplotlib di default. Ogni oggetto asse contiene un itertools.cycle che sequenzialmente cambia il colore predefinito per ogni riga che viene tracciata su tale asse:

ax = plt.axes() 

ax_color_cycle = ax._get_lines.color_cycle 

print(ax_color_cycle) 
# <itertools.cycle object at 0x7fdb91efae60> 

print(ax_color_cycle.next()) 
# b 

print(ax_color_cycle.next()) 
# g 

print(ax_color_cycle.next()) 
# r 

# etc. 
+0

Così forse la possibilità di iniziare l'itertools.cycle con il colore rosso dopo !? Sai quanti colori ci sono nel set, prima che il ciclo ricominci? – user3265764

+0

Intendi il ciclo di colori predefinito? Puoi testarlo da solo facendo '[ax_color_cycle.next() per ii in xrange (10)] '- vedrai che ti dà' ['b', 'g', 'r', 'c', 'm', 'y', 'k' , 'b', 'g', 'r'] ', cioè ripete ogni 8 righe. –

+0

ok, thx. questo è nel mio caso sfavorevole. Ho bisogno di più di una barra di colore. – user3265764