Obtenir des couleurs individuelles à partir d'une carte de couleurs dans matplotlib

136

Si vous avez une palette de couleurs cmap, par exemple:

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

Comment pouvez-vous obtenir une couleur particulière entre 0 et 1, où 0 est la première couleur de la carte et 1 la dernière couleur de la carte?

Idéalement, je pourrais obtenir la couleur du milieu de la carte en faisant:

>>> do_some_magic(cmap, 0.5) # Return an RGBA tuple
(0.1, 0.2, 0.3, 1.0)
LondresRob
la source

Réponses:

219

Vous pouvez le faire avec le code ci-dessous, et le code de votre question était en fait très proche de ce dont vous aviez besoin, tout ce que vous avez à faire est d'appeler l' cmapobjet que vous avez.

import matplotlib

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

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

Pour les valeurs en dehors de la plage [0.0, 1.0], il renverra respectivement les couleurs sous et sur. C'est, par défaut, la couleur minimale et maximale dans la plage (donc 0,0 et 1,0). Cette valeur par défaut peut être modifiée avec cmap.set_under()et cmap.set_over().

Pour les nombres "spéciaux" tels que np.nanet np.infla valeur par défaut est d'utiliser la valeur 0.0, cela peut être changé en utilisant de la cmap.set_bad()même manière que sous et au-dessus comme ci-dessus.

Enfin, il peut être nécessaire pour vous de normaliser vos données afin qu'elles soient conformes à la plage [0.0, 1.0]. Cela peut être fait en utilisant matplotlib.colors.Normalizesimplement comme indiqué dans le petit exemple ci-dessous où les arguments vminet vmaxdécrivent quels nombres doivent être mappés à 0,0 et 1,0 respectivement.

import matplotlib

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

print(norm(15.0)) # 0.5

Un normaliseur logarithmique ( matplotlib.colors.LogNorm ) est également disponible pour les plages de données avec une large plage de valeurs.

(Merci à Joe Kington et à tcaswell pour leurs suggestions sur la façon d'améliorer la réponse.)

Ffisegydd
la source
3
En fait, pour les valeurs inférieures à 0 ou supérieures à 1, il renverra la couleur «over» ou «under». Par défaut, c'est la couleur en bas / en haut de la palette de couleurs, mais c'est modifiable. Par exemple: cmap.set_under('red'); print cmap(0.0), cmap(-0.01)
Joe Kington
Salut @Joe, merci pour la correction, j'ai modifié ma réponse :)
Ffisegydd
Il y a aussi set_badqui définit ce que fait pour np.nanet np.infiirc. Vous devriez également mentionner les Normalizeméthodes ici.
tacaswell
12
Informations très utiles et pourquoi diable est-il impossible de trouver cela dans la documentation!?!
Jaap Eldering
10
Si cela ne fonctionne pour personne, et vous voyez module 'matplotlib' has no attribute 'cm', essayez de remplacer les deux premières lignes parimport matplotlib.pyplot as plt; cmap = plt.cm.get_cmap('Spectral')
Anonyme
9

Afin d'obtenir une valeur entière rgba au lieu d'une valeur flottante, nous pouvons faire

rgba = cmap(0.5,bytes=True)

Donc, pour simplifier le code en fonction de la réponse de Ffisegydd, le code serait comme ceci:

#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
la source
0

Pour construire sur les solutions de Ffisegydd et amaliammr , voici un exemple où nous créons une représentation CSV pour une palette de couleurs personnalisée:

#! /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
la source
0

Pour être complet, voici les choix cmap que j'ai rencontrés jusqu'à présent:

Accent, Accent_r, Blues, Blues_r, BrBG, BrBG_r, BuGn, BuGn_r, BuPu, BuPu_r, CMRmap, CMRmap_r, Dark2, Dark2_r, GnBu, GnBu_r, Verts, Greens_r, Grays, Greys_ranges, OrRd_Rd PRGn_r, Apparié, Paired_r, Pastel1, Pastel1_r, Pastel2, Pastel2_r, PiYG, PiYG_r, PuBu, PuBuGn, PuBuGn_r, PuBu_r, PuOr, PuOr_r, PuRd, PuRd_r, Purples, PurB_Pr, RduPr, RduGr, Rdu_R, Rdu_R, RdP_R, Rdu_R RdYlBu, RdYlBu_r, RdYlGn, RdYlGn_r, Reds, Reds_r, Set1, Set1_r, Set2, Set2_r, Set3, Set3_r, Spectral, Spectral_r, Wistia, Wistia_r, YlGn, YlGnOrBu, YlGn, YlGnOrBu, YlGn, YlGnOrBu, YlGnr YlGnBu, YlGlRdr YlROrBu, YlGlRdR afmhot_r, automne, automne_r, binaire, binary_r, os, bone_r, brg, brg_r, bwr, bwr_r, cividis, cividis_r, cool, cool_r, coolwarm, coolwarm_r, cuivre, cuivre_r, cubehelix, cubehelix_r, drapeau, drapeau_r, gist_earth_earth, gist_earthgist_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, gist_ncar, gist_ncar_r, gist_rainbow, gist_rainbow_r, gist_stern, gist_stern_r, gist_yarg, gist_yarg_r, gist_ncar, gist_ncar_r, gist_rainbow, gist_rainbow_r, gist_stern, gist_stern_r, gist_yarg, gist_yarg_r, gist_ncar, gist_ncar_r, gist_rainbow, gist_rainbow_r, gist_stern, gist_stern_r, gist_yarg, gist_yarg_r, gnuplot, gnuplot2, gnuplot, gnuplot2 jet_r, magma, magma_r, nipy_spectral, nipy_spectral_r, océan, ocean_r, rose, pink_r, plasma, plasma_r, prisme, prism_r, arc en ciel, rainbow_r, sismique, sismic_r, printemps, printemps_r, été, summer_r, tab10, tab10_r, tab20_r, tab20 tab20b, tab20b_r, tab20c, tab20c_r, terrain, terrain_r, crépuscule, twilight_r, twilight_shifted, twilight_shifted_r, viridis, viridis_r, hiver, hiver_rgray_r, chaud, hot_r, hsv, hsv_r, enfer, inferno_r, jet, jet_r, magma, magma_r, nipy_spectral, nipy_spectral_r, océan, ocean_r, rose, pink_r, plasma, plasma_r, prisme, prisme_r, arc-en-ciel, séisme_risme, séisme_risme printemps, spring_r, été, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, terrain, terrain_r, twilight, twilight_r, twilight_shifted, twilight_shifted_r, viridis, viridis_r, hiver, hiver_rgray_r, chaud, hot_r, hsv, hsv_r, enfer, inferno_r, jet, jet_r, magma, magma_r, nipy_spectral, nipy_spectral_r, océan, ocean_r, rose, pink_r, plasma, plasma_r, prisme, prisme_r, arc-en-ciel, séisme_risme, séisme_risme printemps, printemps_r, été, été_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, terrain, terrain_r, crépuscule, twilight_r, twilight_shifted, twilight_shifted_r, viridis, viridis_r, hiver, hiver_rviridis, viridis_r, hiver, hiver_rviridis, viridis_r, hiver, hiver_r

prosti
la source