☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

ColumnDataSource.on_change() callback is not triggering

Community Support
jaemarie
jaemarie

Hello Bokeh Community,

I am using a select widget to update data stored in a ColumnDataSource. I am trying to have a callback function run every time the ColumnDataSource’s data is changed, but it is currently not working.

Here is a simplified version of my code:

from bokeh.models import ColumnDataSource, Select
from bokeh.io import output_file, show
from bokeh.plotting import curdoc
from functools import partial

def update_cds_from_select(level, attr, old, new):
    data = map_state.data
    data['values'][level] =  new
    map_state.data = dict(data)
    
def cds_update_callback(attr, old, new):
    print('ColumnDataSource source was updated')

null_value = '---'

select_region_options = [null_value,'Northern', 'Eastern', 'Southern', 'Western']
select1 = Select(title='Region',options=select_region_options, value=null_value) 
select1.on_change('value', partial(update_cds_from_select, 0))

map_state_data = {'levels': ['NAME_1', 'NAME_2', 'NAME_3', 'NAME_4'],
              'values': [null_value, null_value, null_value, null_value]
              }
map_state = ColumnDataSource(map_state_data)
map_state.on_change('data', cds_update_callback)

curdoc().add_root(select1)

I’m hoping that someone more experienced can point out where I am going wrong. Thank you in advance!

⌁   Link to post
p-himik
p-himik

By the time your code gets to the map_state.data = dict(data) line, the values are already the same since you have changed the data within the map_state.data object. Wrapping it in dict() doesn’t help because Bokeh checks for equality by value, not by reference.

In this particular case you can just replace the whole body of update_cds_from_select with:

map_state.patch(dict(values=[(level, new)]))
⌁   Link to post

End of archived discussion · Replies are disabled