☰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

Pass extra parameters to a python callback

Community Support
epifanio
epifanio

I am trying to pass a pandas data frame as input parameters to a callback but I got “TypeError: ‘DataFrame’ objects are mutable, thus they cannot be hashed” - code snipped: gist:6f5f20a270d6ecb92afd22be22edfa83 · GitHub

from functools import partial
from bokeh.plotting import curdoc
from bokeh.models.widgets import Select
from bokeh.layouts import widgetbox
import pandas as pd

raw_data = {'var_1': ['a', 'b', 'c', 'd', 'e'], 
        'var_2': [1, 2, 3, 4, 5]}
df = pd.DataFrame(raw_data, columns = ['var_1', 'var_2'])


items = ['var_1','var_1']
select = Select(title="Select variable:", value=items[0], options=items)

def callback_select(df, old, new):
    print(df[new])    

select.on_change(df, partial(callback_select))

layout = widgetbox(select)
curdoc().add_root(layout)
⌁   Link to post
epifanio
epifanio

i hardcoded df in this example, in reality it comes from a netcdf-url given to bokeh server as an argument in the url.

Based on the data-source behind the netcdf-url, my plotting routine changes a little … so I was trying to store the bokeh code in different functions - and call the appropriate one based on the type of netcdf.

My plotting routine and its callbacks is working fine if outside a function - a temporary-demo looks like:

https://bokeh.epinux.com/test/app5?url=https://hyrax.epinux.com/opendap/SN99938.nc

but if I move the plotting code in a function that returns the cuurdoc … it will work for the first rendering, but then the callbacks will no longer have access to the elements defined in the code.

I am now thinking that maybe this approach is wrong and
I should simply add more logic to handle the different cases in a single plotting routine - without defining rendering functions based on the url content

⌁   Link to post
p-himik
p-himik

If you use df from an outer scope, it will have the value that’s in the outer scope. It’s as simple as that. Meaning, if that callback is called after you populate df with the right data, that callback will have the right data.

⌁   Link to post
epifanio
epifanio

@p-himik thanks for the pointer - eventually I managed to get this to work following your advice :slight_smile:

In my use case the data-frame is generated by combining xarray and pandas - the code reads an url pointing to a netcdf resource.
In such a context the resulting dataframe can be quite different based on the data structure, e.g.:

  • a netcdf containing a time series will generate a time-indexed dataframe
  • while time series profile will generate a multi-index data-frame (a vertical profile for each time-stamp)
    So I needed the plotting routine to behave differently based on the data-source structure.

I ended up in adding a method to check the df structure and creating different callbacks chosen and attached to the relative widget based on the df structure (e.g.: datetime tooltip in case of time-series, slider widget to switch timestamped vertical profiles in case of time-series-profile … label’s text based on netcdf attributes and so on …)

⌁   Link to post

End of archived discussion · Replies are disabled