Obtendo cores individuais de um mapa de cores no matplotlib

136

Se você possui um mapa de cores cmap, por exemplo:

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

Como você pode obter uma cor específica entre 0 e 1, onde 0 é a primeira cor no mapa e 1 é a última cor no mapa?

Idealmente, eu seria capaz de obter a cor do meio no mapa fazendo:

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

Respostas:

219

Você pode fazer isso com o código abaixo, e o código na sua pergunta estava realmente muito próximo do que você precisava, tudo o que você precisa fazer é chamar o cmapobjeto que você possui.

import matplotlib

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

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

Para valores fora do intervalo [0,0, 1,0], ele retornará as cores abaixo e acima (respectivamente). Por padrão, essa é a cor mínima e máxima dentro do intervalo (portanto, 0,0 e 1,0). Este padrão pode ser alterado com cmap.set_under()e cmap.set_over().

Para números "especiais" como, por exemplo, np.nane np.info padrão é usar o valor 0,0, isso pode ser alterado usando-se da cmap.set_bad()mesma forma que abaixo e acima como acima.

Por fim, pode ser necessário normalizar seus dados de forma que estejam em conformidade com o intervalo [0.0, 1.0]. Isso pode ser feito usando matplotlib.colors.Normalizesimplesmente como mostrado no pequeno exemplo abaixo, onde os argumentos vmine vmaxdescrevem quais números devem ser mapeados para 0,0 e 1,0, respectivamente.

import matplotlib

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

print(norm(15.0)) # 0.5

Um normalizador logarítmico ( matplotlib.colors.LogNorm ) também está disponível para intervalos de dados com um grande intervalo de valores.

(Agradecemos a Joe Kington e tcaswell por sugestões de como melhorar a resposta.)

Ffisegydd
fonte
3
Na verdade, para valores menores que 0 ou mais que 1, ele retornará a cor "acima" ou "abaixo". Por padrão, é a cor na parte inferior / superior do mapa de cores, mas é mutável. Por exemplo: cmap.set_under('red'); print cmap(0.0), cmap(-0.01)
Joe Kington
Oi @ Joe, obrigado pela correção, eu modifiquei a minha resposta :)
Ffisegydd
Há também set_badquem define o que faz para np.nane o np.infiirc. Você deve mencionar os Normalizemétodos aqui também.
precisa saber é o seguinte
12
Informações muito úteis e por que diabos é impossível encontrar isso na documentação!?!
Jaap Ancianidade
10
Se isso não está funcionando para ninguém, e você vê module 'matplotlib' has no attribute 'cm', tente substituir as duas primeiras linhas comimport matplotlib.pyplot as plt; cmap = plt.cm.get_cmap('Spectral')
Anônimo
9

Para obter o valor inteiro rgba em vez do valor flutuante, podemos fazer

rgba = cmap(0.5,bytes=True)

Portanto, para simplificar o código com base na resposta de Ffisegydd, o código seria assim:

#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
fonte
0

Para desenvolver as soluções de Ffisegydd e amaliammr , aqui está um exemplo em que criamos representação CSV para um mapa de cores 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
fonte
0

Para completar, estas são as opções de cmap que encontrei até agora:

Accent, Accent_r, Blues, Blues_r, BrBG, BrBG_r, BuGn, BuGn_r, BuPu, BuPu_r, CMRmap, CMRmap_r, Dark2, Dark2_r, GnBu, GnBu_r, Verdes, Greens_r, Cinzas, Greys_r, OrRd, OrRd_r, Laranjas, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Oranges, Ore PRGn_r, Emparelhado, Emparelhado_r, Pastel1, Pastel1_r, Pastel2, Pastel2_r, PiYG, PiYG_r, PuBu, PuBuGn, PuBuGn_r, PuBu_r, PuOr, PuOr_r, PuRd, PuRd_r, Roxo, Purples_r, RdBu, RdBu_r, RdGy, RdGy, RdGy RdYlBu, RdYlBu_r, RdYlGn, RdYlGn_r, Vermelhos, Reds_r, Conjunto1, Conjunto1_r, Conjunto2, Conjunto2_r, Conjunto3, Conjunto3_r, Espectral, Espectral_r, Wistia, Wistia_r, YlGn, YlGnBu, YlGnBu_r, YlGdR, YlGdR afmhot_r, outono, autumn_r, binário, binary_r, osso, bone_r, brg, brg_r, bwr, bwr_r, cividis, cividis_r, legal, cool_r, coolwarm, coolwarm_r, cobre, copper_r, cubehelix, cubehelix_r, bandeira, flag_r, gist_earth, gist_earth_r,Gist_gray, gist_gray_r, gist_heat, gist_heat_r, gist_ncar, gist_ncar_r, gist_rainbow, gist_rainbow_r, gist_stern, gist_stern_r, gist_yarg, gist_yarg_r, gnuplot, gnuplot2, gnuplot2, gnuplot2, h jet_r, magma, magma_r, nipy_spectral, nipy_spectral_r, oceano, ocean_r, rosa, pink_r, plasma, plasma_r, prisma, prism_r, arco-íris, rainbow_r, sísmica, sismic_r, primavera, spring_r, verão, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, terreno, terrenoin, crepúsculo, crepúsculo_r, crepúsculo_shifted, crepúsculo_shifted_r, viridis, viridis_r, inverno, winter_rgray_r, quente, hot_r, hsv, hsv_r, inferno, inferno_r, jato, jet_r, magma, magma_r, nipy_spectral, nipy_spectral_r, oceano, ocean_r, rosa, pink_r, plasma, plasma_r, prisma, prism_r, arco-íris, rainbow_r, sísmico, sísmico, primavera, spring_r, verão, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, terreno, terrenoin_r, crepúsculo, crepúsculo, crepúsculo_r, crepúsculo_shifted, crepúsculo_shifted_r, viridis, viridis_r, inverno, winter_rgray_r, quente, hot_r, hsv, hsv_r, inferno, inferno_r, jato, jet_r, magma, magma_r, nipy_spectral, nipy_spectral_r, oceano, ocean_r, rosa, pink_r, plasma, plasma_r, prisma, prism_r, arco-íris, rainbow_r, sísmico, sísmico, primavera, spring_r, verão, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, terreno, terrenoin_r, crepúsculo, crepúsculo, crepúsculo_r, crepúsculo_shifted, crepúsculo_shifted_r, viridis, viridis_r, inverno, winter_rviridis, viridis_r, inverno, winter_rviridis, viridis_r, inverno, winter_r

prosti
fonte