I try to implement several sliders and use an own function, foo
, to calculate new values to update the plot. I tried to modify the example from the documentation, but without success; the page loads, I can move the sliders but the plot does not update (please note that I want to use a function I cannot define in javascript; I now use foo
just for illustration purposes).
There must be an issue with the callback
(see entire code below):
def callback(source=source):
data = source.data
a_dynamic = cb_obj.a_slider.value # cb_obj.get('a_slider')
b_dynamic = cb_obj.b_slider.value
x, y = data['x'], data['y']
y = foo(x, a_dynamic, b_dynamic)
source.change.emit()
I don't know how
1) to access the slider values correctly (using cb_obj.<slider_id>.value
, or cb_obj.get(<slider_id>)
or something completely else?)
2) to give the slider an actual ID; the title
argument is only the text that appears above the slider but is probably not its ID and using the id
argument does not work the way I use it.
How would I do this correctly?
import numpy as np
from bokeh.layouts import row, widgetbox
from bokeh.models import CustomJS, Slider
from bokeh.plotting import figure, output_file, show, ColumnDataSource
import bokeh
bokeh.io.reset_output()
def foo(xval, a, b):
return np.power(xval, a) + b
# some artificial data
a0 = 2.
b0 = 1.
x = np.linspace(-100., 100, 1000)
y = foo(x, a0, b0)
source = ColumnDataSource(data=dict(x=x, y=y))
plot = figure(plot_width=400, plot_height=400)
plot.line('x', 'y', source=source, line_width=3, line_alpha=0.6)
def callback(source=source):
data = source.data
a_dynamic = cb_obj.a_slider.value # cb_obj.get('a_slider')
b_dynamic = cb_obj.b_slider.value
x, y = data['x'], data['y']
y = foo(x, a_dynamic, b_dynamic)
source.change.emit()
a_slider_obj = Slider(start=0, end=3, value=a0, step=0.1, id='a_slider',
title="a_slider", callback=CustomJS.from_py_func(callback))
# callback.args["a_slider"] = a_slider_obj
b_slider_obj = Slider(start=-4, end=4, value=b0, step=0.5, id='b_slider',
title="b_slider", callback=CustomJS.from_py_func(callback))
# callback.args["b_slider"] = b_slider_obj
layout = row(
plot,
widgetbox(a_slider_obj, b_slider_obj),
)
show(layout)
EDIT:
Seems that this actually does not work but that one should use the bokeh server for this. I leave the question open for now in case someone wants to post the solution using the server. I then either accept this answer, add an own one or delete the question again if no answer appears.