Abrufen einzelner Farben aus einer Farbkarte in matplotlib

136

Wenn Sie eine Farbkarte haben cmap, zum Beispiel:

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

Wie können Sie eine bestimmte Farbe zwischen 0 und 1 herausholen, wobei 0 die erste Farbe in der Karte und 1 die letzte Farbe in der Karte ist?

Im Idealfall kann ich die mittlere Farbe in der Karte erhalten, indem ich Folgendes mache:

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

Antworten:

219

Sie können dies mit dem folgenden Code tun, und der Code in Ihrer Frage war tatsächlich sehr nahe an dem, was Sie brauchten. Alles, was Sie tun müssen, ist, das cmapObjekt aufzurufen, das Sie haben.

import matplotlib

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

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

Bei Werten außerhalb des Bereichs [0.0, 1.0] wird die Unter- bzw. Überfarbe zurückgegeben. Dies ist standardmäßig die minimale und maximale Farbe innerhalb des Bereichs (also 0,0 und 1,0). Diese Standardeinstellung kann mit cmap.set_under()und geändert werden cmap.set_over().

Für "spezielle" Zahlen wie np.nanund np.infstandardmäßig wird der Wert 0.0 verwendet. Dies kann cmap.set_bad()ähnlich wie oben und unten geändert werden .

Schließlich müssen Sie Ihre Daten möglicherweise so normalisieren, dass sie dem Bereich entsprechen [0.0, 1.0]. Dies kann matplotlib.colors.Normalizeeinfach wie im kleinen Beispiel unten gezeigt erfolgen, in dem die Argumente vminund die vmaxBeschreibung der Zahlen auf 0.0 bzw. 1.0 abgebildet werden sollen.

import matplotlib

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

print(norm(15.0)) # 0.5

Ein logarithmischer Normalisierer ( matplotlib.colors.LogNorm ) ist auch für Datenbereiche mit einem großen Wertebereich verfügbar.

(Vielen Dank an Joe Kington und tcaswell für Vorschläge zur Verbesserung der Antwort.)

Ffisegydd
quelle
3
Bei Werten unter 0 oder mehr als 1 wird die Farbe "über" oder "unter" zurückgegeben. Standardmäßig ist es die Farbe am unteren / oberen Rand der Farbkarte, aber das kann geändert werden. Zum Beispiel: cmap.set_under('red'); print cmap(0.0), cmap(-0.01)
Joe Kington
Hallo @Joe, danke für die Korrektur, ich habe meine Antwort geändert :)
Ffisegydd
Es gibt auch set_badwelche definieren, was in für np.nanund np.infiirc tut. Sie sollten auch Normalizehier die Methoden erwähnen .
Tacaswell
11
Sehr nützliche Informationen und warum um alles in der Welt ist es unmöglich, dies in der Dokumentation zu finden!?!
Jaap Eldering
9
Wenn dies für niemanden funktioniert und Sie sehen module 'matplotlib' has no attribute 'cm', versuchen Sie, die ersten beiden Zeilen durchimport matplotlib.pyplot as plt; cmap = plt.cm.get_cmap('Spectral')
Anonymous
9

Um einen rgba-Integer-Wert anstelle eines Float-Werts zu erhalten, können wir dies tun

rgba = cmap(0.5,bytes=True)

Um den Code basierend auf der Antwort von Ffisegydd zu vereinfachen, würde der Code folgendermaßen aussehen:

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

Um auf den Lösungen von Ffisegydd und amaliammr aufzubauen , sehen Sie hier ein Beispiel, in dem wir eine CSV-Darstellung für eine benutzerdefinierte Farbkarte erstellen:

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

Der Vollständigkeit halber sind dies die cmap-Optionen, auf die ich bisher gestoßen bin:

Akzent, Akzent_r, Blues, Blues_r, BrBG, BrBG_r, BuGn, BuGn_r, BuPu, BuPu_r, CMRmap, CMRmap_r, Dark2, Dark2_r, GnBu, GnBu_r, Grüne, Grüne_r, Grau, Grau_r, Orrd, Orrd PRGn_r, Paired, Paired_r, Pastel1, Pastel1_r, Pastel2, Pastel2_r, PiYG, PiYG_r, PuBu, PuBuGn, PuBuGn_r, PuBu_r, PuOr, PuOr_r, PuRd, PuRd_r, Rdu, RdYlBu, RdYlBu_r, RdYlGn, RdYlGn_r, Rottöne, Rottöne_r, Set1, Set1_r, Set2, Set2_r, Set3, Set3_r, Spektral, Spektral_r, Wistia, Wistia_r, YlGn, YlGnrr, YlGn, YlGnrr afmhot_r, herbst, herbst_r, binär, binär_r, knochen, knochen_r, brg, brg_r, bwr, bwr_r, cividis, cividis_r, cool, cool_r, coolwarm, coolwarm_r, kupfer, kupfer_r, cubehelix, cubehelix_r, flag, flag_r, gisteargist_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, gnuplot_, gnuplot_ jet_r, magma, magma_r, nipy_spectral, nipy_spectral_r, Ozean, ocean_r, pink, pink_r, Plasma, plasma_r, Prisma_prism_r, Regenbogen, Regenbogen_r, seismisch, seismisch_r, Frühling, Frühling_r, Sommer, Sommer_r, tab10, tab10_r, tab20, tab20_r tab20b, tab20b_r, tab20c, tab20c_r, Gelände, Gelände_r, Dämmerung, Dämmerung_r, Dämmerung_verschoben, Dämmerung_verschoben_r, Viridis, Viridis_r, Winter, Winter_rgrau_r, heiß, heiß_r, hsv, hsv_r, Inferno, Inferno_r, Jet, Jet_r, Magma, Magma_r, nipy_spectral, nipy_spectral_r, Ozean, Ozean_r, rosa, pink_r, Plasma, Plasma_r, Prisma, Prisma, Regenbogen, Regenbogen, seismisch Frühling, Frühling_r, Sommer, Sommer_r, Tab10, Tab10_r, Tab20, Tab20_r, Tab20b, Tab20b_r, Tab20c, Tab20c_r, Gelände, Terrain_r, Dämmerung, Dämmerung_r, Dämmerung_verschoben, Dämmerung_verschoben_r, Viridis, Viridis_r, Winter, Winter_rgrau_r, heiß, heiß_r, hsv, hsv_r, Inferno, Inferno_r, Jet, Jet_r, Magma, Magma_r, nipy_spectral, nipy_spectral_r, Ozean, Ozean_r, rosa, pink_r, Plasma, Plasma_r, Prisma, Prisma, Regenbogen, Regenbogen, seismisch Frühling, Frühling_r, Sommer, Sommer_r, Tab10, Tab10_r, Tab20, Tab20_r, Tab20b, Tab20b_r, Tab20c, Tab20c_r, Gelände, Terrain_r, Dämmerung, Dämmerung_r, Dämmerung_verschoben, Dämmerung_verschoben_r, Viridis, Viridis_r, Winter, Winter_rviridis, viridis_r, winter, winter_rviridis, viridis_r, winter, winter_r

Prosti
quelle