Si vous avez une palette de couleurs de
cmap = matplotlib.cm.get_cmap('Spectral')
comment obtenir une couleur particulière entre 0 et 1, où 0.0 est la première couleur de la carte et 1.0 la dernière de la carte?
Idéalement, je pourrais obtenir la couleur moyenne de la carte en faisant:
>>> do_some_magic(cmap, 0.5) # Return an RGBA tuplet
(0.1, 0.2, 0.3, 1.0)
Vous pouvez le faire avec le code ci-dessous, et le code de votre question était en réalité très proche de ce dont vous aviez besoin, il vous suffit d'appeler l'objet cmap
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 situées en dehors de la plage [0.0, 1.0], les couleurs inférieure et supérieure sont renvoyées (respectivement). Ceci, par défaut, est la couleur minimum et maximum 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.nan
Et np.inf
, La valeur par défaut consiste à utiliser la valeur 0.0; vous pouvez la modifier à l'aide de cmap.set_bad()
de la même manière que ci-dessus et plus bas.
Enfin, vous devrez peut-être normaliser vos données de manière à ce qu'elles se conforment à l'intervalle [0.0, 1.0]
. Ceci peut être fait en utilisant matplotlib.colors.Normalize
simplement comme indiqué dans le petit exemple ci-dessous où les arguments vmin
et vmax
décrivent quels nombres doivent être associé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 normalisateur logarithmique ( matplotlib.colors.LogNorm ) est également disponible pour les plages de données avec une large plage de valeurs.
(Merci à la fois Joe Kington et tcaswell pour leurs suggestions sur la façon d'améliorer la réponse.)
Pour obtenir la valeur entière rgba au lieu de la valeur float, nous pouvons faire
rgba = cmap(0.5,bytes=True)
Donc, pour simplifier le code basé sur la réponse de Ffisegydd, le code ressemblerait à 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
Pour tirer parti des solutions de Ffisegydd et amaliammr , voici un exemple où nous créons une représentation CSV pour une carte 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]))