Reputation: 877
I want to be able to slide through many plots which are the result of simulations accross 3+ dimensions. I am using the Bokeh package via Python.
For simplicity, let's assume I have two dimensions : d, and nc. But nc depends on d in the following way:
if d=100, nc=56,57
if d=20, nc=5,6
And I have 4 pictures:
d_100_nc_56.png,
d_100_nc_57.png,
d_20_nc_5.png,
d_20_nc_6.png
So I want two sliders, one for d, and one for nc, to cycle the .png images through the image_url function of Bokeh.plotting.Figure . However, the value of the nc slider should update itself as I change the slider in d
from bokeh.io import vform
from bokeh.models import CustomJS, ColumnDataSource, Slider
from bokeh.plotting import Figure, output_file, show
output_file('image.html')
source = ColumnDataSource(data=dict(url=['d_100_nc_55.png']))
p = Figure(x_range=(0,1), y_range=(0,1))
callback_nc = CustomJS(args=dict(source=source), code="""
var data = source.get('data');
var f = cb_obj.get('value')
old = data['url'][0]
to_replace=old.substring(old.lastIndexOf("nc_")+3,old.lastIndexOf(".png"))
data['url'][0] = old.replace(to_replace,f.toString(10))
source.trigger('change');
""")
callback_d = CustomJS(args=dict(source=source), code="""
var data = source.get('data');
var f = cb_obj.get('value')
old = data['url'][0]
to_replace=old.substring(old.lastIndexOf("d_")+2,old.lastIndexOf("_nc_"))
data['url'][0] = old.replace(to_replace,f.toString(10))
source.trigger('change');
""")
p.image_url('url',source=source, x=0, y=1,w=1,h=1)
p.text(x=0,y=0,text=source.data['url'])
slider_nc = Slider(start=55, end=65, value=1, step=1, title="nc", callback=callback_nc)
slider_d = Slider(start=20, end=100, value=100, step=80, title="density", callback=callback_d)
layout = vform(slider_nc,slider_d, p)
show(layout)
However, I do not know how to pass the d slider as an argument to the nc slider to fetch its properties and update them on the fly. Is this possible ? Otherwise it limits the use of multiple sliders through bokeh quite substantially.
Upvotes: 2
Views: 1914
Reputation: 34568
Edit: updated for more recent versions
You pass the slider the same way you pass source
, as an item in the args
dictionary. Any Python-side Bokeh model you pass there is automatically made available to the callback. Then, BokehJS model properties exactly match the python properties described in the reference guide Here is an example that updates one slider based off another:
# Example from Bokeh 0.12.x
from bokeh.plotting import show, output_file
from bokeh.layouts import column
from bokeh.models import CustomJS, Slider
s1 = Slider(start=1, end=10, value=1, step=1)
s2 = Slider(start=0, end=1, value=0, step=1)
s1.callback = CustomJS(args=dict(s1=s1, s2=s2), code="""
s2.end = s1.value;
""")
output_file("foo.html")
show(column(s1,s2))
Upvotes: 7