hacer - libreria matplotlib python
Establecer diferentes colores para cada serie en el gráfico de dispersión en matplotlib (5)
Una solución fácil
También puede cambiar los colores después de que los haya 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 necesitas:
#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'')
El resultado le ofrece diferentes colores, incluso cuando tiene muchos diagramas de dispersión diferentes en la misma subtrama.
Supongamos que tengo tres conjuntos de datos:
X = [1,2,3,4]
Y1 = [4,8,12,16]
Y2 = [1,4,9,16]
Puedo dispersar la trama esto:
from matplotlib import pyplot as plt
plt.scatter(X,Y1,color=''red'')
plt.scatter(X,Y2,color=''blue'')
plt.show()
¿Cómo puedo hacer esto con 10 juegos?
Busqué esto y pude encontrar cualquier referencia a lo que estoy preguntando.
Editar: clarificando (con suerte) mi pregunta
Si llamo a scatter varias veces, solo puedo configurar 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 distribuir de forma automática mis múltiples conjuntos de datos, cada uno con un color diferente?
Si eso ayuda, puedo asignar fácilmente un número único a cada conjunto de datos.
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 asignar: matriz de cadena de nombre de color, matriz de número de flotante con mapa de color, matriz de RGB o RGBA.
esta respuesta está dedicada a la infinita pasión de @ Oxinabox por corregir la versión 2013 de mí mismo en 2015.
tiene dos opciones para usar el comando scatter con múltiples colores en una sola llamada.
como
pylab.scatter
comandopylab.scatter
use la matriz RGBA para hacer el color que desee;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 aplicarse a dibujar colección de ruta, colección de líneas ...
el código también está inspirado en el código fuente de pyplot.scatter
, simplemente pyplot.scatter
lo que scatter hace sin desencadenarlo.
el comando pyplot.scatter
devuelve un objeto PatchCollection
, en el archivo "matplotlib / collections.py" una variable privada _facecolors
en la clase Collection
y un método set_facecolors
.
así que cuando tengas puntos de dispersión para dibujar puedes 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()
La forma normal de trazar gráficos con puntos en diferentes colores en matplotlib es pasar una lista de colores como parámetro.
P.ej:
import matplotlib.pyplot
matplotlib.pyplot.scatter([1,2,3],[4,5,6],color=[''red'',''green'',''blue''])
Cuando tiene una lista de listas y quiere que se coloreen 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 quieres hacerlo con una sola llamada, puedes hacer una gran lista de colores, con una lista de comprensión y un poco de división de pisos:
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)
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])]
No sé a qué te refieres con "manualmente". Puede elegir un mapa de colores y hacer una matriz de colores con la suficiente 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 haga su propia cicladora de color usando itertools.cycle
y especificando los colores sobre los que desea pasar el bucle, usando al next
para obtener el que desea. Por ejemplo (soy demasiado vago para escribir diez colores):
colors = itertools.cycle(["r", "b", "g"])
for y in ys:
plt.scatter(x, y, color=next(colors))
Ahora que lo pienso, quizás es más limpio no usar 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))
[PD: Realmente odio que tenga que soltar ''u'' cuando trabajo con matplotlib ..]
Siempre puedes usar la función plot()
como sigue:
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()