Нелинейная карта цветов/тепловая карта

Я пытаюсь сделать 1D тепловую карту для гена (например, см. ссылку 1 в pastebin). Я приблизился к тому, что ищу, с помощью контура, но я не смог понять, как получить именно то, что я ищу. По сути, я хочу использовать палитру с 10 дискретными цветами, а отсечки для разных цветов соответствуют процентилю данных (таким образом, верхние 10% точек данных красные, следующие 10% — оранжевые и т. д.).

У меня недостаточно репутации, чтобы публиковать более двух ссылок или изображений, поэтому вы также можете увидеть мои выходные изображения из приведенного ниже кода, а также другие страницы, которые я просмотрел, чтобы попытаться решить этот вопрос, на http://pastebin.com/jAkxyQsK.

Фактические точки данных находятся в списке по адресу http://pastebin.com/3TrkkpZ0. Вы можете попробовать использовать случайные целые числа, но разница между линейным масштабированием и процентильным масштабированием, скорее всего, не будет ясна, если ваши данные не будут искажены, как мои.

data = [] #actually a list of ~450 floats 
x = []
nd = np.array(data)
x = np.empty([2, nd.shape[0]])
x[:,:] = nd

fig = plt.figure(figsize = (11, 8.5))
ax = fig.add_subplot(111)

А теперь мои эксперименты:

mind, maxd, sprd = min(data), max(data), max(data)-min(data)
levels = [(lambda n: mind + (n*sprd)/10)(n) for n in range(0,11,1)]
hm = plt.contourf(x, levels = levels, cmap = "rainbow")
cbar = fig.colorbar(hm, ax = ax)
plt.show()

[Figure 1 on pastebin]

В основном это то, что я хочу видеть: цветная полоса дискретизирована, и график выглядит нормально, но цветовая полоса линейно разнесена между максимальным и минимальным значением данных, а это не то, что мне нужно. Попытка вторая:

levels = np.percentile(data, [z for z in range (0,110,10)])
hm = plt.contourf(x, levels = levels, cmap = "rainbow")
cbar = fig.colorbar(hm, ax = ax)
plt.show()

[Figure 2 on pastebin]

Это тоже близко; цветовая полоса разделена значениями процентилей (или, по крайней мере, значения галочки указывают на это), но по какой-то причине она больше не использует весь диапазон цветовой карты, и я понятия не имею, почему.

Я также пытался реализовать функцию, описанную в ссылках 2 и 3, с помощью pcolor, но я не мог понять, как заставить их работать с моими данными вместо точечной диаграммы, и результаты были не так близки, как я мог бы получить с помощью контура, поэтому Я перестал их преследовать. Если ответ уже есть в одной из ссылок, которые я просматривал, но я не мог его понять, то перевод на «простой английский» был бы очень полезен.


person Emmett    schedule 15.09.2015    source источник


Ответы (1)


Я не могу сказать, почему цветовая карта не использует полный диапазон цветов в вашем примере, но кажется, что следующее ближе к желаемому результату (т.е. оно охватывает больший диапазон цветов с уровнями квантилей).

...
hm = plt.contourf(x, levels = levels, cmap = "rainbow", vmax = levels[-2])
...

Вы также можете попробовать «взвешенное» значение для максимального уровня цветовой карты.

...
hm = plt.contourf(x, levels = levels, cmap = "rainbow", vmax = 0.3 * levels[-1] + 0.7 * levels[-2])
...
person michalis    schedule 15.09.2015
comment
Спасибо за предложение - я думаю, что первое - это то, что я ищу, но, честно говоря, я не знаю, почему оно работает. Можете ли вы объяснить, что делает vmax? - person Emmett; 21.09.2015
comment
Привет. Если вы не указываете его явно, значение vmax является максимальным значением ваших данных и окрашивается в верхний предел цветового спектра палитры. Например, для цветовой карты «радуга» vmax отображается на красный цвет. Когда вы устанавливаете vmax на более низкое значение, вы говорите, что верхняя часть цветового спектра (красный для «радуги») должна использоваться для окрашивания всех значений в ваших данных, которые по крайней мере не ниже вашего vmax. - person michalis; 23.09.2015