Отрегулируйте цветовую карту в боке головидения в соответствии с распределением значений

Я создал карту в Holoviews в блокноте jupyter с расширением боке, используя следующие параметры:

%output size=150
%opts Overlay [show_legend=True, width=800 height=400]
%opts Points.Data [color_index='b' size_index='a' scaling_factor=10 colorbar=True](cmap='RdYlGn' size=3)

И b, и a - переменные в диапазоне от -1 до 1.

Это вызывает две проблемы (также сравните изображение):

  1. размер точек соответствует абсолютному значению переменной 'a'. Однако я бы хотел, чтобы значения создавали меньшие (большие) точки, чем более отрицательное (положительное) значение. Любое решение для этого (кроме изменения масштаба «a» в положительный диапазон перед построением графика)?
  2. Поскольку положительных значений 'b' значительно больше, чем отрицательных, почти все точки a отображаются в зеленый цвет, в то время как отрицательная часть цветового диапазона используется очень редко. Я не хочу преобразовывать 'b', поскольку его значение имеет смысл, который я хотел бы отображать в цветовой легенде. Есть предложения, как настроить цветовую карту, чтобы лучше отразить распределение значений «b»?

Я новичок в holoviews / bokeh и еще не привык к синтаксису. Поэтому я также был бы признателен за образец кода.

введите описание изображения здесь


person Nini    schedule 09.07.2018    source источник


Ответы (2)


Ответ на ваш первый вопрос довольно прост: Points поддерживает параметр size_fn, который вы можете использовать для преобразования значений размера перед построением чего-то простого, например, смещения точек на 1, будет работать. Второй вопрос сложнее, и на него нет однозначного ответа. Если есть очень мало точек ниже 0, я бы подумал, является ли расходящаяся палитра правильным выбором. Возможно, просто установите диапазон измерения цвета на 0-1, используйте стандартную цветовую карту и установите специальный цвет для значений за пределами диапазона.

# Make some fake data
lon, lat = np.random.rand(2, 100)*180-90
a = np.clip((np.random.randn(100) + 1)/2., -1, 1)
b = np.clip((np.random.randn(100) + 1)/2., -1, 1)
df = pd.DataFrame({'lon': lon, 'lat': lat, 'a': a, 'b': b})

gv.tile_sources.EsriImagery * gv.Points(df, ['lon', 'lat']).options(
    width=600, height=400, color_index='a', size_fn=lambda x: x+1, 
    scaling_factor=20, size_index='b', colorbar=True, cmap='Greens', 
    clipping_colors={'min': "red"}
).redim.range(a=(0, 1))

введите описание изображения здесь

В приведенном выше примере я использовал size_fn, чтобы сместить значения цвета на единицу, чтобы все они были положительными и могли масштабироваться. Во-вторых, я использовал метод .redim.range, чтобы установить диапазон значений цвета от 0 до 1. Наконец, я использовал clipping_colors, чтобы сказать, что любые значения ниже min (0) должны быть окрашены в красный цвет.

person philippjfr    schedule 09.07.2018

Чтобы ответить на # 2, вы можете создать свою собственную цветовую карту из цветовой карты по умолчанию и удалить любое количество цветов с концов цветовой карты (изменяя начало / конец), как это

from matplotlib.colors import LinearSegmentedColormap
import matplotlib.pyplot as plt
cmap_name = 'RdBu_r'
start = 0.4
stop = 1
n = 256
cmap = plt.get_cmap(cmap_name)
colors = cmap(np.linspace(start, stop, cmap.N))
new_cmap = LinearSegmentedColormap.from_list('mycmap', colors=colors, N=n)

а затем сделайте points = points.redim.range(data=(-0.2, 1))

В качестве примера ниже я вырезал все синие оттенки из RdBu_r, оставив только красные https://holoext.readthedocs.io/en/latest/examples/changing_colorbar_cmap.html#Colorbar-string-shortcut

person Andrew    schedule 11.07.2018