How do I update the bokeh colorbar with a new colormap?

I am trying to figure out how to update the color map of the color bar using a drop-down select button, but so far no success.


I thought that just setting something like this would work:

color_bar.color_mapper = new_color_mapper

And it does work but only as long as it is not included inside the update function. Here’s an example using the file from the bokeh website:

import numpy as np
from import curdoc
from bokeh.plotting import figure
from bokeh.layouts import layout
from bokeh.models.widgets import Select
from bokeh.models import ColorBar, LinearColorMapper

cbar = Select(title="colormap", value="Spectral11",
              options=["Spectral11", "Viridis11"], width=120)

N = 500
x = np.linspace(0, 10, N)
y = np.linspace(0, 10, N)
xx, yy = np.meshgrid(x, y)
d = np.sin(xx)*np.cos(yy)

p = figure(tooltips=[("x", "$x"), ("y", "$y"), ("value", "@image")])
p.x_range.range_padding = p.y_range.range_padding = 0

img = p.image(image=[d], x=0, y=0, dw=10, dh=10, palette="Spectral11")

color_mapper = LinearColorMapper(palette="Spectral11", low=-1, high=1)
color_bar = ColorBar(color_mapper=color_mapper, 
                    width=10, location=(0,0))

p.add_layout(color_bar, 'right')

# adding color_bar.color_mapper = some_new_color_mapper here works

def update():
    color_mapper = LinearColorMapper(palette=cbar.value)
    img.glyph.color_mapper = color_mapper
    # this doesn't work
    color_bar.color_mapper = color_mapper

cbar.on_change('value', lambda attr, old, new: update())
l = layout([p, cbar])

I don’t know what I’m missing here.

The general, always-applicable best-practice rule with Bokeh is: always make the smallest change possible . In this context (and usually) that means updating simple properties of existing objects (i.e. the palette property of the existing color mapper), rather than trying to replace entire bokeh object.

def update():
    img.glyph.color_mapper.palette = cbar.value
    color_bar.color_mapper.palette = cbar.value
1 Like