Obtener colores individuales de un mapa de colores en matplotlib

136

Si tiene un mapa de colores cmap, por ejemplo:

cmap = matplotlib.cm.get_cmap('Spectral')

¿Cómo puede obtener un color particular de él entre 0 y 1, donde 0 es el primer color en el mapa y 1 es el último color en el mapa?

Idealmente, podría obtener el color del medio en el mapa haciendo:

>>> do_some_magic(cmap, 0.5) # Return an RGBA tuple
(0.1, 0.2, 0.3, 1.0)
LondonRob
fuente

Respuestas:

219

Puede hacer esto con el código a continuación, y el código en su pregunta en realidad estaba muy cerca de lo que necesitaba, todo lo que tiene que hacer es llamar al cmapobjeto que tiene.

import matplotlib

cmap = matplotlib.cm.get_cmap('Spectral')

rgba = cmap(0.5)
print(rgba) # (0.99807766255210428, 0.99923106502084169, 0.74602077638401709, 1.0)

Para valores fuera del rango [0.0, 1.0] devolverá el color inferior y superior (respectivamente). Este, por defecto, es el color mínimo y máximo dentro del rango (por lo tanto, 0.0 y 1.0). Este valor predeterminado se puede cambiar con cmap.set_under()y cmap.set_over().

Para números "especiales" como np.nany np.infel valor predeterminado es usar el valor 0.0, esto se puede cambiar usando de cmap.set_bad()manera similar a under y over como se indicó anteriormente.

Finalmente, puede ser necesario que normalice sus datos de manera que se ajusten al rango [0.0, 1.0]. Esto se puede hacer usando matplotlib.colors.Normalizesimplemente como se muestra en el pequeño ejemplo a continuación, donde los argumentos vminy vmaxdescriben qué números deben asignarse a 0.0 y 1.0 respectivamente.

import matplotlib

norm = matplotlib.colors.Normalize(vmin=10.0, vmax=20.0)

print(norm(15.0)) # 0.5

También está disponible un normalizador logarítmico ( matplotlib.colors.LogNorm ) para rangos de datos con un amplio rango de valores.

(Gracias a Joe Kington y tcaswell por sus sugerencias sobre cómo mejorar la respuesta).

Ffisegydd
fuente
3
En realidad, para valores inferiores a 0 o superiores a 1 devolverá el color "sobre" o "debajo". Por defecto es el color en la parte inferior / superior del mapa de colores, pero eso se puede cambiar. Por ejemplo: cmap.set_under('red'); print cmap(0.0), cmap(-0.01)
Joe Kington
Hola @ Joe, gracias por la corrección, he modificado mi respuesta :)
Ffisegydd
También hay set_badque definen qué hace para np.nane np.infiirc. Deberías mencionar los Normalizemétodos aquí también.
tacaswell
12
¡Información muy útil y por qué es imposible encontrar esto en la documentación!
Jaap Eldering
10
Si esto no funciona para nadie, y ve module 'matplotlib' has no attribute 'cm', intente reemplazar las dos primeras líneas conimport matplotlib.pyplot as plt; cmap = plt.cm.get_cmap('Spectral')
Anónimo
9

Para obtener el valor entero rgba en lugar del valor flotante, podemos hacer

rgba = cmap(0.5,bytes=True)

Entonces, para simplificar el código basado en la respuesta de Ffisegydd, el código sería así:

#import colormap
from matplotlib import cm

#normalize item number values to colormap
norm = matplotlib.colors.Normalize(vmin=0, vmax=1000)

#colormap possible values = viridis, jet, spectral
rgba_color = cm.jet(norm(400),bytes=True) 

#400 is one of value between 0 and 1000
amaliammr
fuente
0

Para construir sobre las soluciones de Ffisegydd y amaliammr , aquí hay un ejemplo en el que hacemos una representación CSV para un mapa de colores personalizado:

#! /usr/bin/env python3
import matplotlib
import numpy as np 

vmin = 0.1
vmax = 1000

norm = matplotlib.colors.Normalize(np.log10(vmin), np.log10(vmax))
lognum = norm(np.log10([.5, 2., 10, 40, 150,1000]))

cdict = {
    'red':
    (
        (0., 0, 0),
        (lognum[0], 0, 0),
        (lognum[1], 0, 0),
        (lognum[2], 1, 1),
        (lognum[3], 0.8, 0.8),
        (lognum[4], .7, .7),
    (lognum[5], .7, .7)
    ),
    'green':
    (
        (0., .6, .6),
        (lognum[0], 0.8, 0.8),
        (lognum[1], 1, 1),
        (lognum[2], 1, 1),
        (lognum[3], 0, 0),
        (lognum[4], 0, 0),
    (lognum[5], 0, 0)
    ),
    'blue':
    (
        (0., 0, 0),
        (lognum[0], 0, 0),
        (lognum[1], 0, 0),
        (lognum[2], 0, 0),
        (lognum[3], 0, 0),
        (lognum[4], 0, 0),
    (lognum[5], 1, 1)
    )
}


mycmap = matplotlib.colors.LinearSegmentedColormap('my_colormap', cdict, 256)   
norm = matplotlib.colors.LogNorm(vmin, vmax)
colors = {}
count = 0
step_size = 0.001
for value in np.arange(vmin, vmax+step_size, step_size):
    count += 1
    print("%d/%d %f%%" % (count, vmax*(1./step_size), 100.*count/(vmax*(1./step_size))))
    rgba = mycmap(norm(value), bytes=True)
    color = (rgba[0], rgba[1], rgba[2])
    if color not in colors.values():
        colors[value] = color

print ("value, red, green, blue")
for value in sorted(colors.keys()):
    rgb = colors[value]
    print("%s, %s, %s, %s" % (value, rgb[0], rgb[1], rgb[2]))
Morten
fuente
0

Para completar, estas son las opciones de cmap que encontré hasta ahora:

Acento, Acento_r, Blues, Blues_r, BrBG, BrBG_r, BuGn, BuGn_r, BuPu, BuPu_r, CMRmap, CMRmap_r, Dark2, Dark2_r, GnBu, GnBu_r, Greens, Greens_r, Greys, Greys_r, OrRd, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr PRGn_r, Emparejado, Emparejado_r, Pastel1, Pastel1_r, Pastel2, Pastel2_r, PiYG, PiYG_r, PuBu, PuBuGn, PuBuGn_r, PuBu_r, PuOr, PuOr_r, PuRd, PuRd_r, Purples, Purples_r, RdBu, RdG, Rd, RdP, Rd, RdP, Rd, RdP, Rd, RdP , Y, A afmhot_r, otoño, otoño_r, binario, binario_r, hueso, hueso_r, brg, brg_r, bwr, bwr_r, cividis, cividis_r, cool, cool_r, coolwarm, coolwarm_r, cobre, cobre_r, cubehelix, cubehelix_r, bandera, flag_arth, gist_e, gist_e, gist_e, gist_e, gf. jet_r, magma, magma_r, nipy_spectral, nipy_spectral_r, ocean, ocean_r, pink, pink_r, plasma, plasma_r, prism, prism_r, rainbow, rainbow_r, seismic, seismic_r, spring, spring_r, summer, summer_r, tab10, tab10_r, tab20, tab20, tab20, tab20, tab20, tab20 tab20b, tab20b_r, tab20c, tab20c_r, terreno, terreno_r, crepúsculo, twilight_r, twilight_shifted, twilight_shifted_r, viridis, viridis_r, invierno, invierno_rgray_r, hot, hot_r, hsv, hsv_r, inferno, inferno_r, jet, jet_r, magma, magma_r, nipy_spectral, nipy_spectral_r, ocean, ocean_r, pink, pink_r, plasma, plasma_r, prism, prism_r, rainbow, rainbow_r, sismr, sismic, primavera, primavera_r, verano, verano_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, terreno, terreno_r, crepúsculo, twilight_r, twilight_shifted, twilight_shifted_r, viridis, viridis_r, invierno, winter_rgray_r, hot, hot_r, hsv, hsv_r, inferno, inferno_r, jet, jet_r, magma, magma_r, nipy_spectral, nipy_spectral_r, ocean, ocean_r, pink, pink_r, plasma, plasma_r, prism, prism_r, rainbow, rainbow_r, sismr, sismic, primavera, primavera_r, verano, verano_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, terreno, terreno_r, crepúsculo, twilight_r, twilight_shifted, twilight_shifted_r, viridis, viridis_r, invierno, winter_rviridis, viridis_r, invierno, invierno_rviridis, viridis_r, invierno, invierno_r

prosti
fuente