Heatmap color update from js_on_change ? Should something be specified in LinearColorMapper?

If you change the dimension and open the JavaScript console, you will see there a very clear error indicating what’s wrong with your code.

With that being said, there’s a better way to do it - without shuffling the data around. You can just change the field, transform.low, and transform.high:

from pandas import *

from bokeh.io import show
from bokeh.layouts import column
from bokeh.models import LinearColorMapper, Select, CustomJS
from bokeh.palettes import Viridis256
from bokeh.plotting import figure

df = DataFrame({'attribute': ['Y', 'Y', 'Y', 'Y', 'Z', 'Z', 'Z', 'Z']
                   , 'period': [1, 2, 3, 4, 1, 2, 3, 4]
                   , 'dimension_1': [1, 37, 44, 13, 41, 51, 18, 14]
                   , 'dimension_2': [10, 3, 44, 53, 20, 9, 18, 14]
                   , 'dimension_3': [80, 37, 22, 13, 13, 44, 18, 14]})

df['period'] = df['period'].astype(str)
periods = df.period.unique().tolist()
attributes = df.attribute.unique().tolist()

active = 'dimension_1'
values_select = Select(title="Values:", options=["dimension_1", "dimension_2", 'dimension_3'], value=active)
color_mapper = LinearColorMapper(palette=Viridis256, low=df[active].min(), high=df[active].max())
p = figure(x_range=periods, y_range=attributes)
renderer = p.rect(x="period", y="attribute", width=1, height=1, line_color=None, source=df,
                  fill_color={'field': 'dimension_1', 'transform': color_mapper})

values_select.js_on_change('value', CustomJS(args=dict(renderer=renderer, p=p), code="""\
    const active = cb_obj.value;
    const data = renderer.data_source.data[active];
    const {transform} = renderer.glyph.fill_color;
    transform.low = Math.min(...data);
    transform.high = Math.max(...data);
    renderer.glyph.fill_color = {field: cb_obj.value, transform: transform};
    p.reset.emit()
"""))

show(column([values_select, p]))
1 Like