Получение отдельных цветов из цветовой карты в matplotlib

136

Если у вас есть Colormap 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)
LondonRob
источник

Ответы:

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()аналогично under и over, как указано выше.

Наконец, вам может понадобиться нормализовать ваши данные так, чтобы они соответствовали диапазону [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 ) также доступен для диапазонов данных с большим диапазоном значений.

(Спасибо Джо Кингтону и Тэсвеллу за предложения о том, как улучшить ответ.)

Ffisegydd
источник
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')
Anonymous
9

Чтобы получить целочисленное значение rgba вместо значения с плавающей запятой, мы можем сделать

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
amaliammr
источник
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]))
Morten
источник
0

Для полноты вот те варианты cmap, с которыми я столкнулся:

Accent, Accent_r, Блюз, Blues_r, BrBG, BrBG_r, BuGn, BuGn_r, BuPu, BuPu_r, CMRmap, CMRmap_r, Dark2, Dark2_r, GnBu, GnBu_r, Зеленые, Greens_r, Грейс, Грейс-Орж, Орден, Ордж 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, RURG-RURG RdYlBu, RdYlBu_r, RdYlGn, RdYlGn_r, Reds, Reds_r, Set1, Set1_r, Set2, Set2_r, Set3, Set3_r, Спектральный, Spectral_r, Wistia, Wistia_r, YlGn, YlGr-YRL-YRRYRR afmhot_r, осень, autumn_r, двоичный файл, binary_r, кость, bone_r, brg, brg_r, bwr, bwr_r, cividis, cividis_r, классный, cool_r, coolwarm, coolwarm_r, медь, copper_r, cubehelix, cubehelix_r, флаг, flag_r, 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, gnr_2, gnr_2 jet_r, магма, magma_r, nipy_spectral, nipy_spectral_r, океан, ocean_r, розовый, pink_r, плазма, plasma_r, призма, prism_r, радуга, rainbow_r, сейсмическая, сейсмическая_r, весна, spring_r, лето, summer_r, tab10, tab10_r, tab20 tab20b, tab20b_r, tab20c, tab20c_r, местность, terrain_r, сумерки, сумерки_r, сумерки_шифрованные, сумерки_шифрованные_r, виридис, виридис_r, зима, зима_рgray_r, горячий, hot_r, hsv, hsv_r, ад, инферно_r, струя, jet_r, магма, magma_r, nipy_spectral, nipy_spectral_r, океан, ocean_r, розовый, розовый_r, плазма, plasma_r, призма, призма_r, рама, радуга, радуга_r весна, spring_r, лето, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, местность, terrain_r, сумерки, сумерки_r, сумерки_сдвиг, сумерки_шифрованный_р, виридис, зима, зима, зимаgray_r, горячий, hot_r, hsv, hsv_r, ад, инферно_r, струя, jet_r, магма, magma_r, nipy_spectral, nipy_spectral_r, океан, ocean_r, розовый, розовый_r, плазма, plasma_r, призма, призма_r, рама, радуга, радуга_r весна, spring_r, лето, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, местность, terrain_r, сумерки, сумерки_r, сумерки_сдвиг, сумерки_шифрованный_р, виридис, зима, зима, зимавиридис, виридис_р, зима, зима_рвиридис, виридис_р, зима, зима_р

прости
источник