Hi all,
I am using bokeh 2.1.1. I am trying to change the colour of a glyph using js. A checkbox is used to change the colour mapper attached to the glyph.
The glyph is initialised with a CategoricalColorMapper and the correct colour is shown. I am trying to change the colour mapper to a linear_cmap when the checkbox “heat map” is ticked. The new colours are not picked up.
Could you help me to achieve it?
See code example below.
Thanks
from bokeh.plotting import figure
from bokeh.plotting import output_file
from bokeh.plotting import show
from bokeh.models import ColumnDataSource
from bokeh.models import CategoricalColorMapper
from bokeh.transform import linear_cmap
from bokeh.layouts import layout
from bokeh.models.widgets import CheckboxGroup
from bokeh.models.callbacks import CustomJS
output_file("bokeh_change_colour_mapper_from_js.html", title="bokeh colour mapper", mode='inline')
heatmap_color_palette = [
'#0A3278', # (10, 50, 120)
'#0F4BA5', # (15, 75, 165)
'#1E6EC8', # (30, 110, 200)
'#3CA0F0', # (60, 160, 240)
'#50B4FA', # (80, 180, 250)
'#82D2FF', # (130, 210, 255)
'#A0F0FF', # (160, 240, 255)
'#FFE878', # (255, 232, 120)
'#FFC03C', # (255, 192, 60)
'#FFA000', # (255, 160, 0)
'#FF5F00', # (255, 95, 0)
'#FF3200', # (255, 50, 0)
'#E11400', # (225, 20, 0)
'#C00000', # (192, 0, 0)
'#A50000' # (165, 0, 0)
]
circle_data = {
'x': [1, 9, 4, 7, 2, 5, 3, 6],
'y': [1, 9, 4, 7, 2, 5, 3, 6],
'size': [9, 9, 6, 6, 9, 9, 6, 6],
'desc': ['desc_1', 'desc_9', 'desc_4', 'desc_7', 'desc_2', 'desc_5', 'desc_3', 'desc_6'],
'sensitivity': [2, 7, 9, 9, 1, 2, 8, 6]
}
color_mapper_from_sensitivity = linear_cmap('sensitivity', heatmap_color_palette, 0, 10)
color_mapper_from_desc = CategoricalColorMapper(
factors=['desc_1', 'desc_9', 'desc_4', 'desc_7', 'desc_2', 'desc_5', 'desc_3', 'desc_6'],
palette=['#330000', '#FF0000', '#FFFF00', '#00FF00', '#00FFFF', '#0000FF', '#7F00FF', '#FF007F']
)
p = figure(
x_axis_type='datetime',
plot_width=800, plot_height=800,
background_fill_color='#DCDCDC', background_fill_alpha=0.4
)
circle_data_source = ColumnDataSource(circle_data)
circle_renderer = p.circle(
x='x', y='y', size='size', source=circle_data_source,
fill_color={'field': 'desc', 'transform': color_mapper_from_desc},
muted_alpha=0.2,
line_color=None)
code = """
// the event that triggered the callback is cb_obj:
// The event type determines the relevant attributes
//console.log('Tap event occurred at x-position: ' + cb_obj.x)
console.log('active: ' + this.active)
console.log('active: ' + cb_obj.active)
if (this.active.length) {
circle_renderer.glyph.color = color_mapper_from_sensitivity
}
else {
circle_renderer.glyph.color = {'field': 'train_desc', 'transform': color_mapper_from_desc}
}
circle_data_source.change.emit()
circle_renderer.change.emit()
p.change.emit()
return
"""
callback = CustomJS(
args=dict(
p=p, circle_renderer=circle_renderer,
circle_data_source=circle_data_source,
color_mapper_from_desc=color_mapper_from_desc,
color_mapper_from_sensitivity=color_mapper_from_sensitivity
),
code=code
)
checkbox_group = CheckboxGroup(labels=["Heat map"], active=[])
checkbox_group.js_on_click(handler=callback)
l = layout([
[checkbox_group],
[p],
])
show(l)