tiempo real matrices graficos graficas graficar coordenadas python matplotlib colorbar

python - real - Matplotlib-agrega barra de color a una secuencia de gráficos de líneas



matplotlib python 3 (4)

(Sé que esta es una vieja pregunta, pero ...) Las barras de colores requieren un matplotlib.cm.ScalarMappable , plt.plot produce líneas que no son escalares mapeable, por lo tanto, para hacer una barra de color, vamos a necesitar hacer una escalar mappable

De acuerdo. Entonces, el constructor de un ScalarMappable toma un cmap y una instancia de norm . (las normas escalan los datos al rango 0-1, cmaps con los que ya ha trabajado y toman un número entre 0-1 y devuelve un color). Entonces en tu caso:

import matplotlib.pyplot as plt sm = plt.cm.ScalarMappable(cmap=my_cmap, norm=plt.normalize(min=0, max=1)) plt.colorbar(sm)

Como sus datos ya están en el rango 0-1, puede simplificar la creación de sm para:

sm = plt.cm.ScalarMappable(cmap=my_cmap)

Espero que ayude a alguien.

EDITAR : para matplotlib v1.2 o superior, el código se convierte en:

import matplotlib.pyplot as plt sm = plt.cm.ScalarMappable(cmap=my_cmap, norm=plt.normalize(vmin=0, vmax=1)) # fake up the array of the scalar mappable. Urgh... sm._A = [] plt.colorbar(sm)

EDITAR : para matplotlib v1.3 o superior, el código se convierte en:

import matplotlib.pyplot as plt sm = plt.cm.ScalarMappable(cmap=my_cmap, norm=plt.Normalize(vmin=0, vmax=1)) # fake up the array of the scalar mappable. Urgh... sm._A = [] plt.colorbar(sm)

Tengo una secuencia de gráficos de líneas para dos variables (x, y) para varios valores diferentes de una variable z. Normalmente agregaría los gráficos de líneas con leyendas como esta:

import matplotlib.pyplot as plt fig = plt.figure() ax = fig.add_subplot(111) # suppose mydata is a list of tuples containing (xs, ys, z) # where xs and ys are lists of x''s and y''s and z is a number. legns = [] for(xs,ys,z) in mydata: pl = ax.plot(xs,ys,color = (z,0,0)) legns.append("z = %f"%(z)) ax.legends(legns) plt.show()

Pero tengo demasiados gráficos y las leyendas cubrirán el gráfico. Prefiero tener una barra de color que indique el valor de z correspondiente al color. No puedo encontrar nada como eso en la galería y todos mis intentos si tratan con la barra de color han fallado. Aparentemente debo crear una colección de parcelas antes de intentar agregar una barra de colores.

¿Hay una forma fácil de hacer esto? Gracias.

EDITAR (aclaración):

Yo quería hacer algo como esto:

import matplotlib.pyplot as plt import matplotlib.cm as cm fig = plt.figure() ax = fig.add_subplot(111) mycmap = cm.hot # suppose mydata is a list of tuples containing (xs, ys, z) # where xs and ys are lists of x''s and y''s and z is a number between 0 and 1 plots = [] for(xs,ys,z) in mydata: pl = ax.plot(xs,ys,color = mycmap(z)) plots.append(pl) fig.colorbar(plots) plt.show()

Pero esto no funcionará de acuerdo con la referencia de Matplotlib porque una lista de parcelas no es "asignable", sea lo que sea lo que esto signifique.

LineCollection una función de trazado alternativa usando LineCollection :

def myplot(ax,xs,ys,zs, cmap): plot = lc([zip(x,y) for (x,y) in zip(xs,ys)], cmap = cmap) plot.set_array(array(zs)) x0,x1 = amin(xs),amax(xs) y0,y1 = amin(ys),amax(ys) ax.add_collection(plot) ax.set_xlim(x0,x1) ax.set_ylim(y0,y1) return plot

xs y ys son listas de listas de coordenadas xey, y zs es una lista de las diferentes condiciones para colorear cada línea. Sin embargo, se siente un poco como un escándalo ... pensé que habría una manera más clara de hacer esto. Me gusta la flexibilidad de la función plt.plot() .


Aquí hay un ejemplo ligeramente simplificado inspirado en la respuesta principal dada por y (¡Gracias por la gran idea!):

1. Barra de colores discreta

La barra de color discreta está más involucrada, porque el mapa de mpl.cm.get_cmap() generado por mpl.cm.get_cmap() no es una imagen asignable necesaria como un argumento de colorbar() . Se debe generar un dummie mappable como se muestra a continuación:

import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl n_lines = 5 x = np.linspace(0, 10, 100) y = np.sin(x[:, None] + np.pi * np.linspace(0, 1, n_lines)) c = np.arange(1, n_lines + 1) cmap = mpl.cm.get_cmap(''jet'', n_lines) fig, ax = plt.subplots(dpi=100) # Make dummie mappable dummie_cax = ax.scatter(c, c, c=c, cmap=cmap) # Clear axis ax.cla() for i, yi in enumerate(y.T): ax.plot(x, yi, c=cmap(i)) fig.colorbar(dummie_cax, ticks=c) plt.show();

Esto producirá una trama con una barra de colores discreta:

2. Barra de color continua

La barra de color continua es menos complicada, ya que mpl.cm.ScalarMappable() nos permite obtener una "imagen" para colorbar() .

import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl n_lines = 5 x = np.linspace(0, 10, 100) y = np.sin(x[:, None] + np.pi * np.linspace(0, 1, n_lines)) c = np.arange(1, n_lines + 1) norm = mpl.colors.Normalize(vmin=c.min(), vmax=c.max()) cmap = mpl.cm.ScalarMappable(norm=norm, cmap=mpl.cm.jet) cmap.set_array([]) fig, ax = plt.subplots(dpi=100) for i, yi in enumerate(y.T): ax.plot(x, yi, c=cmap.to_rgba(i + 1)) fig.colorbar(cmap, ticks=c) plt.show();

Esto producirá una trama con una barra de color continua:

[Nota al cmap.set_array([]) ] En este ejemplo, personalmente no sé por qué es necesario cmap.set_array([]) (de lo contrario, obtendríamos mensajes de error). Si alguien entiende los principios bajo el capó, por favor comente :)


Como otras respuestas aquí intentan usar gráficos ficticios, lo cual no es realmente un buen estilo, aquí hay un código genérico para un

Discreta barra de color

Se produce una barra de color discreta de la misma manera que se crea una barra de color continua, solo con una normalización diferente. En este caso, se debe usar una BoundaryNorm .

import numpy as np import matplotlib.pyplot as plt import matplotlib.colors n_lines = 5 x = np.linspace(0, 10, 100) y = np.sin(x[:, None] + np.pi * np.linspace(0, 1, n_lines)) c = np.arange(1., n_lines + 1) cmap = plt.get_cmap("jet", len(c)) norm = matplotlib.colors.BoundaryNorm(np.arange(len(c)+1)+0.5,len(c)) sm = plt.cm.ScalarMappable(norm=norm, cmap=cmap) sm.set_array([]) fig, ax = plt.subplots(dpi=100) for i, yi in enumerate(y.T): ax.plot(x, yi, c=cmap(i)) fig.colorbar(sm, ticks=c) plt.show()


Esta es una forma de hacerlo mientras se usa plt.plot (). Básicamente, haces una trama desechable y obtienes la barra de colores desde allí.

import matplotlib as mpl import matplotlib.pyplot as plt min, max = (-40, 30) step = 10 # Setting up a colormap that''s a simple transtion mymap = mpl.colors.LinearSegmentedColormap.from_list(''mycolors'',[''blue'',''red'']) # Using contourf to provide my colorbar info, then clearing the figure Z = [[0,0],[0,0]] levels = range(min,max+step,step) CS3 = plt.contourf(Z, levels, cmap=mymap) plt.clf() # Plotting what I actually want X=[[1,2],[1,2],[1,2],[1,2]] Y=[[1,2],[1,3],[1,4],[1,5]] Z=[-40,-20,0,30] for x,y,z in zip(X,Y,Z): # setting rgb color based on z normalized to my range r = (float(z)-min)/(max-min) g = 0 b = 1-r plt.plot(x,y,color=(r,g,b)) plt.colorbar(CS3) # using the colorbar info I got from contourf plt.show()

Es un poco derrochador, pero conveniente. Tampoco es muy derrochador si haces varias parcelas, ya que puedes llamar a plt.colorbar () sin regenerar la información para ello.