Отримання окремих кольорів з кольорової карти в matplotlib


136

Якщо у вас є кольорова карта cmap, наприклад:

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

Як можна отримати певний колір з нього між 0 і 1, де 0 - перший колір на карті, а 1 - останній колір на карті?

В ідеалі я міг би отримати середній колір на карті, зробивши:

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

Відповіді:


219

Ви можете зробити це за допомогою наведеного нижче коду, і код у вашому запитанні насправді був дуже близький до того, що вам потрібно, все, що вам потрібно зробити, - це зателефонувати cmapоб'єкту, який у вас є.

import matplotlib

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

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

Для значень поза діапазону [0,0, 1,0] він поверне нижній і над кольором (відповідно). За замовчуванням це мінімальний та максимальний колір у межах діапазону (так 0,0 та 1,0). Цей за замовчуванням можна змінити за допомогою cmap.set_under()та cmap.set_over().

Для "спеціальних" чисел, таких як, np.nanа np.infза замовчуванням є використання значення 0,0, це можна змінити, використовуючи cmap.set_bad()аналогічно до і нижче, як і вище.

Нарешті, вам може знадобитися нормалізувати свої дані таким чином, щоб вони відповідали діапазону [0.0, 1.0] . Це можна зробити, використовуючи matplotlib.colors.Normalizeпросто, як показано в невеликому прикладі нижче, де аргументи vminта vmaxописують, які числа повинні бути відображені відповідно до 0,0 та 1,0.

import matplotlib

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

print(norm(15.0)) # 0.5

Логарифмічний нормалізатор ( matplotlib.colors.LogNorm ) також доступний для діапазонів даних з великим діапазоном значень.

(Дякую і Джо Кінгтону, і Ткасвелл за пропозиції, як поліпшити відповідь.)


3
Насправді, для значень, менших від 0 або більше 1, він поверне колір "понад" або "під". За замовчуванням це колір у нижній / верхній частині кольорової карти, але це змінено. Наприклад: cmap.set_under('red'); print cmap(0.0), cmap(-0.01)
Джо Кінгтон

Привіт @Joe, дякую за виправлення, я змінив свою відповідь :)
Ffisegydd

Існує також , set_badякі визначають , що в робить для np.nanі np.infIIRC. Тут слід згадати і Normalizeметоди.
tacaswell

12
Дуже корисна інформація і чому на землі неможливо знайти це в документації!?!
Яап Старійшина

10
Якщо це не працює для когось, і ви бачите module 'matplotlib' has no attribute 'cm', спробуйте замінити перші два рядки наimport matplotlib.pyplot as plt; cmap = plt.cm.get_cmap('Spectral')
Анонімний

9

Для того щоб отримати ціле значення rgba замість float значення, ми можемо зробити

rgba = cmap(0.5,bytes=True)

Отже, щоб спростити код на основі відповіді від Ffisegydd, код буде таким:

#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

0

Щоб спиратися на рішення Ffisegydd та amaliammr , ось приклад, коли ми робимо CSV-представлення для власної кольорової карти:

#! /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]))

0

Для повноти це вибір cmap, з яким я стикався до цього часу:

Accent, Accent_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, Ord, Ord, Orr 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, Purples, Rples, Rples, Rples, Rples, Rples, Rples, Rples, Rples, Rples, Rples, Rples, Rples, Rples, Rupd, Rples, Rples, Rupd, Rpd, Rpd, Rpd, Rpd, Rd, Rd, Rd, R, R, 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, YlGnr, YlGnBl, YlGnBl, YlGnBl afmhot_r, осінь, осінь_р, бінарний, бінарний_р, кістка, кістка_р, brg, brg_r, bwr, bwr_r, cividis, cividis_r, cool, cool_r, coolwarm, coolwarm_r, мідь, медь_r, cubehelix, cubehelix_r, прапор, flag_th, gist, gist, gist, gistgist_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_r, gnuplot_r, сірий, gray_r, гарячий, hot_r, ВПГ, hsv_r, пекло, inferno_r, струмінь, jet_r, магма, magma_r, nipy_spectral, nipy_spectral_r, океан, океан_r, рожевий, рожевий_р, плазма, плазма_р, призма, призма_р, веселка, веселка_р, сейсмічний, сейсмічний_р, весна, весна_р, літо, літо_р, табл10, таб10_р, табл20, табл10, таб20, таб20, таб20, таб20 tab20b, tab20b_r, tab20c, tab20c_r, рельєф місцевості, місцевість_r, сутінки, сутінки_р, сутінки_смілений, сутінки_схильований_р, viridis, viridis_r, зима, зима_rсірий_r, гарячий, hot_r, hsv, hsv_r, inferno, inferno_r, jet, jet_r, магма, magma_r, nipy_spectral, nipy_spectral_r, океан, океан_r, рожевий, pink_r, плазма, плазма_р, призма, призма, веселка, веселка, веселка, веселка, веселка, веселка весна, spring_r, літо, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, місцевість, terrain_r, сутінки, сутінки_r, twilight_shifted, twilight_shifted_r, viridis, viridis_r, зима, зима, зимасірий_r, гарячий, hot_r, hsv, hsv_r, inferno, inferno_r, jet, jet_r, магма, magma_r, nipy_spectral, nipy_spectral_r, океан, океан_r, рожевий, pink_r, плазма, плазма_р, призма, призма, веселка, веселка, веселка, веселка, веселка, веселка весна, spring_r, літо, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, місцевість, terrain_r, сутінки, сутінки_r, twilight_shifted, twilight_shifted_r, viridis, viridis_r, зима, зима, зимаviridis, viridis_r, зима, зима_рviridis, viridis_r, зима, зима_р

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.