2012-09-02 12 views
95

Supponiamo che io ho tre insiemi di dati:impostazione di colore diverso per ogni serie nel grafico a dispersione sul matplotlib

X = [1,2,3,4] 
Y1 = [4,8,12,16] 
Y2 = [1,4,9,16] 

posso Diagramma a dispersione questo:

from matplotlib import pyplot as plt 
plt.scatter(X,Y1,color='red') 
plt.scatter(X,Y2,color='blue') 
plt.show() 

Come posso fare questo con 10 set?

Ho cercato questo e ho trovato qualsiasi riferimento a ciò che sto chiedendo.

Edit: chiarire (si spera) la mia domanda

Se chiamo scatter più volte, posso solo impostare lo stesso colore su ogni dispersione. Inoltre, so che posso impostare manualmente un array di colori, ma sono sicuro che c'è un modo migliore per farlo. La mia domanda è allora: "Come i miei diversi insiemi di dati, ognuno I disperdere-plot automaticamente con un colore diverso.

se questo aiuta, posso facilmente assegnare un numero univoco per ogni set di dati.

+1

Qual è il quesiton qui? Anche il colore può essere un array, ma cosa non puoi risolvere chiamando semplicemente scatter più volte? – seberg

+1

Se chiamo scatter più volte, ottengo gli stessi colori. Aggiornerò la mia domanda – Yotam

risposta

150

I . non sa cosa si intende per 'manualmente' possibile scegliere un colourmap e fare una serie di colore abbastanza facilmente:

import numpy as np 
import matplotlib.pyplot as plt 
import matplotlib.cm as cm 

x = np.arange(10) 
ys = [i+x+(i*x)**2 for i in range(10)] 

colors = cm.rainbow(np.linspace(0, 1, len(ys))) 
for y, c in zip(ys, colors): 
    plt.scatter(x, y, color=c) 

o creare il proprio cycler colore utilizzando itertools.cycle e specificando i colori che si desidera ciclo finito, utilizzando next per ottenere quello desiderato. Ad esempio (sono troppo pigro per digitare dieci colori s):

colors = itertools.cycle(["r", "b", "g"]) 
for y in ys: 
    plt.scatter(x, y, color=next(colors)) 

Vieni a pensarci bene, forse è più pulita non utilizzare zip con il primo troppo:

colors = iter(cm.rainbow(np.linspace(0, 1, len(ys)))) 
for y in ys: 
    plt.scatter(x, y, color=next(colors)) 

[PS: ho davvero odio che devo cadere la 'u 'quando si lavora con matplotlib ..]

+1

+1. Un ciclo itertools probabilmente non è una buona idea in questa situazione, dato che finirebbe con più set di dati con lo stesso colore. –

+1

@DavidRobinson: non se si specificano tutti e dieci, anche se sono d'accordo sul fatto che il ciclismo ha lo scopo lì ..: ^) – DSM

+0

Precisamente - quindi non è un ciclo :) –

27

Il modo normale di tracciare i grafici con punti in diversi colori in matplotlib consiste nel passare un elenco di colori come parametro.

Es .:

import matplotlib.pyplot 
matplotlib.pyplot.scatter([1,2,3],[4,5,6],color=['red','green','blue']) 

3 colors

Quando si dispone di una lista di liste e si desidera loro colorati per lista. Penso che il modo più elegante sia quello suggerito da @DSM, , basta fare un ciclo per effettuare più chiamate da diffondere.

Ma se per qualche motivo si voleva farlo con una sola chiamata, si può fare una grande lista di colori, con una lista di comprensione e un po 'di divisione pavimenti:

import matplotlib 
import numpy as np 

X = [1,2,3,4] 
Ys = np.array([[4,8,12,16], 
     [1,4,9,16], 
     [17, 10, 13, 18], 
     [9, 10, 18, 11], 
     [4, 15, 17, 6], 
     [7, 10, 8, 7], 
     [9, 0, 10, 11], 
     [14, 1, 15, 5], 
     [8, 15, 9, 14], 
     [20, 7, 1, 5]]) 
nCols = len(X) 
nRows = Ys.shape[0] 

colors = matplotlib.cm.rainbow(np.linspace(0, 1, len(Ys))) 

cs = [colors[i//len(X)] for i in range(len(Ys)*len(X))] #could be done with numpy's repmat 
Xs=X*nRows #use list multiplication for repetition 
matplotlib.pyplot.scatter(Xs,Ys.flatten(),color=cs) 

All plotted

cs = [array([ 0.5, 0. , 1. , 1. ]), 
array([ 0.5, 0. , 1. , 1. ]), 
array([ 0.5, 0. , 1. , 1. ]), 
array([ 0.5, 0. , 1. , 1. ]), 
array([ 0.28039216, 0.33815827, 0.98516223, 1.  ]), 
array([ 0.28039216, 0.33815827, 0.98516223, 1.  ]), 
array([ 0.28039216, 0.33815827, 0.98516223, 1.  ]), 
array([ 0.28039216, 0.33815827, 0.98516223, 1.  ]), 
... 
array([ 1.00000000e+00, 1.22464680e-16, 6.12323400e-17, 
      1.00000000e+00]), 
array([ 1.00000000e+00, 1.22464680e-16, 6.12323400e-17, 
      1.00000000e+00]), 
array([ 1.00000000e+00, 1.22464680e-16, 6.12323400e-17, 
      1.00000000e+00]), 
array([ 1.00000000e+00, 1.22464680e-16, 6.12323400e-17, 
      1.00000000e+00])] 
6

Questa domanda è un po 'complicata prima di gennaio 2013 e matplotlib 1.3.1 (agosto 2013), che è la versione stabile più vecchia che è possibile trovare sul sito web matpplotlib. Ma dopo questo è abbastanza banale.

Poiché la versione attuale dell'assistenza matplotlib.pylab.scatter assegna: matrice di stringa nome colore, matrice di numero a virgola mobile con mappa colori, matrice di RGB o RGBA.

questa risposta è dedicata a @ passione infinita di Oxinabox per correggere la versione 2013 di me stesso nel 2015.


si hanno due possibilità di utilizzare il comando a dispersione con il colore multiplo in una singola chiamata.

  1. come pylab.scatter comando uso supporto RGBA array per fare qualsiasi colore che volete;

  2. indietro all'inizio del 2013, non c'è modo di farlo, dal momento che il comando supporta solo un colore per l'intera collezione punto di dispersione. Quando stavo facendo il mio progetto di 10000 linee, ho trovato una soluzione generale per aggirarlo. quindi è molto cattivo, ma posso farlo in qualsiasi forma, colore, dimensione e trasparenza. questo trucco potrebbe anche essere applicabile a disegnare la raccolta percorso, collezione linea ....

il codice si ispira anche il codice sorgente di pyplot.scatter, ho appena duplicato quello che fa a meno dispersione di innesco per disegnare.

il comando pyplot.scatter restituire un oggetto PatchCollection, nel file "matplotlib/collections.py" una variabile privata _facecolors in Collection classe e un metodo set_facecolors.

in modo ogni volta che avete un punti di dispersione per disegnare si può fare questo:

# rgbaArr is a N*4 array of float numbers you know what I mean 
# X is a N*2 array of coordinates 
# axx is the axes object that current draw, you get it from 
# axx = fig.gca() 

# also import these, to recreate the within env of scatter command 
import matplotlib.markers as mmarkers 
import matplotlib.transforms as mtransforms 
from matplotlib.collections import PatchCollection 
import matplotlib.markers as mmarkers 
import matplotlib.patches as mpatches 


# define this function 
# m is a string of scatter marker, it could be 'o', 's' etc.. 
# s is the size of the point, use 1.0 
# dpi, get it from axx.figure.dpi 
def addPatch_point(m, s, dpi): 
    marker_obj = mmarkers.MarkerStyle(m) 
    path = marker_obj.get_path() 
    trans = mtransforms.Affine2D().scale(np.sqrt(s*5)*dpi/72.0) 
    ptch = mpatches.PathPatch(path, fill = True, transform = trans) 
    return ptch 

patches = [] 
# markerArr is an array of maker string, ['o', 's'. 'o'...] 
# sizeArr is an array of size float, [1.0, 1.0. 0.5...] 

for m, s in zip(markerArr, sizeArr): 
    patches.append(addPatch_point(m, s, axx.figure.dpi)) 

pclt = PatchCollection(
       patches, 
       offsets = zip(X[:,0], X[:,1]), 
       transOffset = axx.transData) 

pclt.set_transform(mtransforms.IdentityTransform()) 
pclt.set_edgecolors('none') # it's up to you 
pclt._facecolors = rgbaArr 

# in the end, when you decide to draw 
axx.add_collection(pclt) 
# and call axx's parent to draw_idle() 
+0

quindi è un po 'complicato da leggere e nel 2013 ho usato python per 1 anno. quindi perché la gente vorrebbe sapere come si fa? dopo averlo fatto funzionare, non mi preoccupo più di guardarlo di nuovo. il mio progetto era disegnare molta visualizzazione, con il codice sopra riportato, il flusso di lavoro è stato semplificato. – Hualin

6

si può sempre utilizzare la funzione plot() in questo modo:

import matplotlib.pyplot as plt 

import numpy as np 

x = np.arange(10) 
ys = [i+x+(i*x)**2 for i in range(10)] 
plt.figure() 
for y in ys: 
    plt.plot(x, y, 'o') 
plt.show() 

plot as scatter but changes colors

9

una soluzione semplice

È inoltre possibile modificare i colori af che li hai tracciati, a volte è più facile da eseguire.

import matplotlib.pyplot as plt 
from random import randint 
import numpy as np 

#Let's generate some random X, Y data X = [ [frst group],[second group] ...] 
X = [ [randint(0,50) for i in range(0,5)] for i in range(0,24)] 
Y = [ [randint(0,50) for i in range(0,5)] for i in range(0,24)] 
labels = range(1,len(X)+1) 

fig = plt.figure() 
ax = fig.add_subplot(111) 
for x,y,lab in zip(X,Y,labels): 
     ax.scatter(x,y,label=lab) 

L'unico pezzo di codice che avete bisogno:

#Now this is actually the code that you need, an easy fix your colors just cut and paste not you need ax. 
colormap = plt.cm.gist_ncar #nipy_spectral, Set1,Paired 
colorst = [colormap(i) for i in np.linspace(0, 0.9,len(ax.collections))]  
for t,j1 in enumerate(ax.collections): 
    j1.set_color(colorst[t]) 


ax.legend(fontsize='small') 

L'uscita ti dà colori differnent anche quando si hanno molti grafici a dispersione diversi nella stessa sottotrama.

enter image description here