Estoy tratando de hacer una barra de colores discreta para un diagrama de dispersión en matplotlib
Tengo mis datos x, y y para cada punto un valor de etiqueta de número entero que quiero que se represente con un color único, por ejemplo
plt.scatter(x, y, c=tag)
normalmente, la etiqueta será un número entero comprendido entre 0 y 20, pero el rango exacto puede cambiar
Hasta ahora acabo de usar la configuración predeterminada, por ejemplo
plt.colorbar()
lo que da una gama continua de colores. Idealmente, me gustaría un conjunto de n colores discretos (n = 20 en este ejemplo). Aún mejor sería obtener un valor de etiqueta de 0 para producir un color gris y 1-20 para ser colorido.
He encontrado algunos guiones de 'libros de cocina', pero son muy complicados y no puedo pensar que sean la forma correcta de resolver un problema aparentemente simple.
fuente
Respuestas:
Puede crear una barra de colores discreta personalizada con bastante facilidad utilizando un BoundaryNorm como normalizador para su dispersión. El bit peculiar (en mi método) es hacer que 0 aparezca como gris.
Para las imágenes, a menudo uso cmap.set_bad () y convierto mis datos en una matriz enmascarada numpy. Sería mucho más fácil convertir 0 en gris, pero no pude hacer que esto funcione con la dispersión o el cmap personalizado.
Como alternativa, puede crear su propio cmap desde cero o leer uno existente y anular solo algunas entradas específicas.
Personalmente, creo que con 20 colores diferentes es un poco difícil leer el valor específico, pero eso depende de usted, por supuesto.
fuente
plt.colorbar.ColorbarBase
lanza Error. Usompl.colorbar.ColorbarBase
N-1
encmap = mpl.colors.LinearSegmentedColormap.from_list('Custom cmap', cmaplist, cmap.N-1)
. Si no, los colores no se distribuyen por igual dentro de los contenedores y tiene un problema de barrera de cerca.q=np.arange(0.0, 1.01, 0.1) cmap = mpl.cm.get_cmap('jet') cmaplist = [cmap(x) for x in q] cmap = mpl.colors.LinearSegmentedColormap.from_list('Custom cmap', cmaplist, len(q)-1) norm = mpl.colors.BoundaryNorm(q, cmap.N)
N-1
, quizás tengas razón, pero no puedo replicarlo con mi ejemplo. Puede evitar elLinearSegmentedColormap
(y suN
argumento) utilizando unListedColormap
. Los documentos han mejorado mucho desde '13, ver por ejemplo: matplotlib.org/3.1.1/tutorials/colors/…Podrías seguir este ejemplo :
que produce la siguiente imagen:
fuente
Las respuestas anteriores son buenas, excepto que no tienen una ubicación adecuada en la barra de colores. Me gusta tener las marcas en el medio del color para que el número -> mapeo de color sea más claro. Puede resolver este problema cambiando los límites de la llamada de matshow:
fuente
set_ticklabels(...)
sólo debe utilizarse para controlar el formato de la etiqueta (por ejemplo, número decimal, etc.). Si los datos son realmente discretos, es posible que no note ningún problema. Si hay ruido en el sistema (por ejemplo, 2 -> 1.9), este etiquetado inconsistente dará como resultado una barra de colores incorrecta y engañosa.Para establecer valores por encima o por debajo del rango del mapa de colores, querrá utilizar los métodos
set_over
yset_under
del mapa de colores. Si desea marcar un valor en particular, enmascarelo (es decir, cree una matriz enmascarada) y use elset_bad
método. (Eche un vistazo a la documentación de la clase de mapa de colores base: http://matplotlib.org/api/colors_api.html#matplotlib.colors.Colormap )Parece que quieres algo como esto:
fuente
Este tema ya está bien cubierto, pero quería agregar algo más específico: quería estar seguro de que un cierto valor se asignaría a ese color (no a cualquier color).
No es complicado, pero como me tomó algo de tiempo, podría ayudar a otros a no perder tanto tiempo como yo :)
fuente
pos
no estoy completamente seguro de por qué está aquí, pero es solicitado por FuncFormatter () ... ¡Quizás alguien más pueda aclararnos al respecto!He estado investigando estas ideas y aquí están mis cinco centavos. Evita llamar
BoundaryNorm
y especificarnorm
como argumento ascatter
ycolorbar
. Sin embargo, no he encontrado la manera de eliminar la llamada bastante prolongada amatplotlib.colors.LinearSegmentedColormap.from_list
.Algunos antecedentes son que matplotlib proporciona los llamados mapas de color cualitativos, destinados a usarse con datos discretos.
Set1
, por ejemplo, tiene 9 colores fácilmente distinguibles ytab20
podría usarse para 20 colores. Con estos mapas podría ser natural usar sus primeros n colores para colorear diagramas de dispersión con n categorías, como lo hace el siguiente ejemplo. El ejemplo también produce una barra de colores con n colores discretos debidamente etiquetados.que produce la imagen de abajo. El
n
en la llamada aSet1
especifica los primerosn
colores de ese mapa de colores, y el últimon
en la llamada afrom_list
especifica la construcción de un mapa conn
colores (el valor predeterminado es 256). Para establecercm
como mapa de colores predeterminado conplt.set_cmap
, encontré que era necesario darle un nombre y registrarlo, a saber:fuente
Creo que querrás mirar colors.ListedColormap para generar tu mapa de colores , o si solo necesitas un mapa de colores estático, he estado trabajando en una aplicación que podría ayudar.
fuente