Update color mapper palette via JS callback


I’m trying to build a widget with a dropdown menu that allows changing the color mapper palette on the fly. Ideally I wanted to do this via a JS callback to be faster. I’ve tried following the user guide, but haven’t had much luck in getting it to work. When add the .js_on_change method, it no longer displays the plot.

Here’s a minimal working example to show this failing (using jupyter notebook):

import numpy as np

from bokeh.io import push_notebook, show, output_notebook

from bokeh.layouts import row, column, widgetbox

from bokeh.plotting import figure

from bokeh.models.mappers import LinearColorMapper

from bokeh.models.widgets import Dropdown

from bokeh.models.callbacks import CustomJS

import bokeh.palettes as bp


data = np.arange(500.**2).reshape((500,500))

color_mapper = LinearColorMapper(palette=“Viridis256”, low=data.min(), high=data.max())

p = figure(plot_width=data.shape[0], plot_height=data.shape[1],

       x_range=(0, data.shape[0]), y_range=(0, data.shape[1]),


img = p.image(image=[data], x=[0], y=[0], dw=[data.shape[0]], dh=[data.shape[1]],


palettes = [(a, a) for a in bp.palettes if a[-3:] == ‘256’]

callback = CustomJS(args=dict(cm=img.glyph.color_mapper), code="""

var c = cb_obj.value;

cm.palette = c;


dropdown = Dropdown(label=“Colour maps”, button_type=“warning”, menu=palettes)

dropdown.js_on_change(‘start’, callback)

show(row(p, widgetbox(dropdown)), notebook_handle=True)

If I don’t have the line dropdown.js_on_change(‘start’, callback), the plots shows normally and I get the dropdown menu (but no action).

What am I doing wrong? Is this not possible?