As ref: http://bokeh.pydata.org/en/latest/docs/user_guide/interaction.html#customjs-with-a-python-function
My code:
df = pd.read_sql_query('select * from data', con=engine)
source = ColumnDataSource(df[df.origin==1])
def callback(source=source, window=None):
source.data = df[df.origin==cb_obj.get('value')].to_dict()
source.trigger('change')
slider = Slider(start=1, end=8, value=1, step=1, title="Origin",
callback=CustomJS.from_py_func(callback))
fig = figure(responsive=True)
fig.circle(source.data['x'], source.data['y'])
layout = column(slider, fig)
show(layout)
Changing the slider does nothing.
Why is this, and what am I supposed to do to explicitly assign new data interactively?
Sorry, I posted a response in error.
What you have cannot work, CustomJS callbacks _only every execute JavaScript, and cannot execute "real" python_
the from_py_func is a convenience that "translates" python to javascript, but only very simple python that does not involve any other libraries, etc, can work in this way. Real calls to libraries like pandas _cannot_ work, because they require real python, and the browser has no way to execute python. Only javascript.
If you need to run real python on your callbacks (e.g, pandas, scikits, etc) you will have to use a bokeh server app, like the ones on https://demo.bokehplots.com
Finally, please use the mailing list for general support questions like this as we reserver the tracke for bug reports and feature requests. There are more people on the mailing list that can potentially help.
@bryevdv thanks for explanation and sorry for opening at wrong place.
While here can you be kind to replay:
source.data (assuming I get dict) and expect bokeh graph to update? For example source.data = some_dict_with_same_scheme. Or do I have to set x, y variables as lists with new values, explicitly.console.log() in JS callback)Hey Rornor, Bryan,
I ran into the same issue and found a sort of hacky solution.
You can also create a dummy/default data source & pass multiple data sources to the callback. Then, iterate through the dummy/default data source in JS deleting all elements of the object and replace it with another data source. I did this with a Selection widget though, not a slider.
Refer to http://stackoverflow.com/questions/43231896/changing-source-of-plot-in-bokeh-with-a-callback
Example:
callback = CustomJS(args={
'source1': source_dummy,
'source2': source_selectionA,
'source3': source_selectionB,
'source4': source_selectionC}, code="""
var data1 = source1.data;
var data2 = source2.data;
var data3 = source3.data;
var data4 = source4.data;
var f = cb_obj.value;
if (f == 'A') {
for (var e in data1) delete data1[e]; //clears the dummy datasource
data1['x'] = data2['x'];
data1['y'] = data2['y'];
}
if (f == 'B') {
for (var e in data1) delete data1[e];
data1['x'] = data3['x']
data1['y'] = data3['y'];
}
if (f == 'C') {
for (var e in data1) delete data1[e];
data1['x'] = data4['x']
data1['y'] = data4['y'];
}
source1.trigger('change');
""")
select = Select(title='Choose', value='A', options=['A','B','C'])
select.js_on_change('value', callback)
Most helpful comment
Hey Rornor, Bryan,
I ran into the same issue and found a sort of hacky solution.
You can also create a dummy/default data source & pass multiple data sources to the callback. Then, iterate through the dummy/default data source in JS deleting all elements of the object and replace it with another data source. I did this with a Selection widget though, not a slider.
Refer to http://stackoverflow.com/questions/43231896/changing-source-of-plot-in-bokeh-with-a-callback
Example: