Сочетание двух цветовых карт matplotlib
Я хотел бы объединить две карты цветов в одну, чтобы я мог использовать одну cmap
для отрицательных значений и другой для положительных значений.
На данный момент я делаю это с массивами в масках и строю одно изображение одним cmap
и другое изображение с другим, в результате чего:
со следующими данными
dat = np.random.rand(10,10) * 2 - 1
pos = np.ma.masked_array(dat, dat<0)
neg = np.ma.masked_array(dat, dat>=0)
Я построил pos
с gist_heat_r
а также neg
с binary
,
Я хотел бы иметь одну цветовую панель с комбинированным cmap
, так что это не правильный подход для меня.
Итак, как мне взять два существующих cmaps
и объединить их в одну?
РЕДАКТИРОВАТЬ: Я признаю, это дубликат, но ответ, который дается здесь, гораздо яснее. Также примеры изображений делают это более ясным.
2 ответа
Цветовые карты - это просто интерполяционные функции, которые вы можете вызывать. Они отображают значения из интервала [0,1] в цвета. Таким образом, вы можете просто выбрать цвета с обеих карт, а затем объединить их:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
data = np.random.rand(10,10) * 2 - 1
# sample the colormaps that you want to use. Use 128 from each so we get 256
# colors in total
colors1 = plt.cm.binary(np.linspace(0., 1, 128))
colors2 = plt.cm.gist_heat_r(np.linspace(0, 1, 128))
# combine them and build a new colormap
colors = np.vstack((colors1, colors2))
mymap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors)
plt.pcolor(data, cmap=mymap)
plt.colorbar()
plt.show()
Результат:
ПРИМЕЧАНИЕ: я понимаю, что у вас могут быть к этому особые потребности, но, на мой взгляд, это не очень хороший подход: как вы будете отличать -0,1 от 0,9? -0,9 от 0,1?
Одним из способов предотвратить это является выборка карт только от ~0,2 до ~0,8 (например: colors1 = plt.cm.binary(np.linspace(0.2, 0.8, 128))
) поэтому они не пройдут весь путь до черного:
Я согласен с принятым ответом, но чтобы не выполнять выборку между ~0,2 и ~0,8, вы можете, например, перевернуть двоичную карту цветов. Вот как это сделать.
colors1 = plt.cm.binary_r(np.linspace(0., 1, 128))
colors2 = plt.cm.gist_heat_r(np.linspace(0, 1, 128))
colors = np.vstack((colors1, colors2))
mymap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors)
plt.pcolor(data, cmap=mymap)
plt.colorbar()
plt.show()
Основное изменение – заменаplt.cm.binary
сplt.cm.binary_r
.