2012-09-02 24 views
95

Supongamos que tengo tres conjuntos de datos:Ajuste de color diferente para cada serie en el gráfico de dispersión en matplotlib

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

puedo Gráfico de dispersión esto:

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

¿Cómo se puede hacer esto con 10 conjuntos?

He buscado esto y podría encontrar cualquier referencia a lo que estoy pidiendo.

Editar: clarificación (con suerte) mi pregunta

Si llamo dispersión en múltiples ocasiones, sólo puedo ajustar el mismo color en cada dispersión. Además, sé que puedo configurar un conjunto de colores manualmente, pero estoy seguro de que hay una mejor manera de hacerlo. Mi pregunta es, entonces, "¿Cómo puedo automáticamente dispersión de las parcelas mis varios conjuntos de datos, cada una con un color diferente.

Si eso ayuda, puedo asignar fácilmente un número único a cada conjunto de datos.

+1

¿Cuál es la pregunta aquí? El color también puede ser una matriz, pero ¿qué no puedes resolver simplemente llamando a scatter varias veces? – seberg

+1

Si llamo a scatter varias veces, obtengo los mismos colores. Actualizaré mi pregunta. – Yotam

Respuesta

150

I . no sabe lo que quiere decir con 'manualmente' se puede elegir un mapa de colores y hacer una matriz de colores con bastante facilidad:

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 hacer su propio ciclador color usando itertools.cycle y especificar los colores que desea reproducir indefinidamente, usando next para obtener el que desee. Por ejemplo (soy demasiado flojo para escribir diez colores s):

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

Ahora que lo pienso de ella, tal vez es más limpio no utilizar zip con el primero también:

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

[PS: Yo realmente odio que tengo que dejar caer la 'U 'cuando se trabaja con matplotlib ..]

+1

+1. Sin embargo, un ciclo de itertools probablemente no sea una buena idea en esta situación, ya que terminaría con múltiples conjuntos de datos que tienen el mismo color. –

+1

@DavidRobinson: no si especificas los diez, aunque estoy de acuerdo en que el ciclismo derrota el propósito allí ...: ^) – DSM

+0

Precisamente, entonces no es un ciclo :) –

27

La forma normal de trazar gráficos con puntos en diferentes colores en matplotlib es pasar una lista de colores como parámetro.

ej .:

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

3 colors

Cuando usted tiene una lista de listas y desea que colorean por lista. Creo que la manera más elegante es la sugerida por @DSM, , simplemente haga un ciclo haciendo múltiples llamadas para dispersar.

Pero si por alguna razón por la que quería hacerlo con sólo una llamada, se puede hacer una gran lista de colores, con una lista por comprensión y un poco de división de suelos:

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

Esta pregunta es un poco complicada antes de enero de 2013 y matplotlib 1.3.1 (agosto de 2013), que es la versión estable más antigua que puede encontrar en el sitio web de matpplotlib. Pero después de eso es bastante trivial.

Porque la versión actual de matplotlib.pylab.scatter admite la asignación de: matriz de cadena de nombre de color, matriz de número de flotante con mapa de color, matriz de RGB o RGBA.

esta respuesta es dedicarse a @ infinita pasión de Oxinabox para corregir la versión 2013 de mí mismo en 2015.


usted tiene dos opciones de utilizar comandos de dispersión con múltiples colores en una sola llamada.

  1. como pylab.scatter comando conjunto utilización apoyo RGBA hacer cualquier color que desee;

  2. a principios de 2013, no hay forma de hacerlo, ya que el comando solo admite un solo color para toda la colección de puntos de dispersión. Cuando estaba haciendo mi proyecto de 10000 líneas, descubrí una solución general para eludirlo. así que es muy hortera, pero puedo hacerlo en cualquier forma, color, tamaño y transparencia. este truco también podría ser aplicable a llamar la colección ruta, recogida línea ....

el código también se inspira en el código fuente de pyplot.scatter, acabo de dispersión duplicado lo hace sin gatillo a dibujar.

el comando pyplot.scatter devolver un objeto PatchCollection, en el archivo "matplotlib/collections.py" una variable privada _facecolors en Collection clase y un método set_facecolors.

así que cuando usted tiene un puntos de dispersión para dibujar se puede hacer esto:

# 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

por lo que es un poco complicado de leer y en 2013 utilicé Python durante 1 año. Entonces, ¿por qué las personas querrían saber cómo hacerlo? después de que funcionó, nunca me molesto en mirarlo de nuevo. mi proyecto fue dibujar mucha visualización, con el código anterior, el flujo de trabajo se simplificó. – Hualin

6

siempre se puede utilizar la función plot() así:

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 solución fácil

También puede cambiar los colores af Si usted los ha trazado, esto a veces es más fácil de realizar.

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) 

La única pieza de código que necesita:

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

La salida le da colores differnent incluso cuando tiene muchos diferentes gráficos de dispersión en la misma trama secundaria.

enter image description here

Cuestiones relacionadas