Mathusalem Mathusalem - 7 months ago 248
Python Question

Sliding through images with Bokeh Slider

I am trying to convey a large amount of scientific data seamlessly with the help of sliders.

I am beginning with Bokeh and have close to no knowledge in javascript. I tried to setup a first approach to be able to slide through two images, but I cannot get the image to refresh.

Suppose I have 1.png and 2.png in my folder.

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=['1.png']))

p = Figure(x_range=(0,1), y_range=(0,1))

callbackimg = CustomJS(args=dict(source=source), code="""
var data = source.get('data');
var f = cb_obj.get('value')
old = data['url'][0]
data['url'][0]= old.replace("1","f")
source.trigger('change');
""")

p.image_url('url',source=source, x=0, y=1,w=1,h=1)
slider = Slider(start=1, end=2, value=1, step=1, title="image number", callback=callbackimg)

layout = vform(slider, p)
show(layout)


I adapted examples from Bokeh Widget Doc for the slider and
working with images in bokeh.

My idea is that the slider, through the callbackimg snippet, will modify the source which contains the url, i.e the name of the image to load.
I thought, for now, that a simple access to the string in the source, and a replacement through the current value of the slider (so it should jump from 1.png to 2.png as the slider goes from 1 to 2) should do the trick.

However, nothing is changing. I suspect I am doing something wrong in the Javascript snippet.

Thanks for any feedback

EDIT: I edited the code according to the suggestions of @bigreddot, but now the slider shows simply an empty figure when sliding in position '2'.
EDIT2: Solved the issue, in my answer below

Answer

The problem is this:

url = data['url'][0]
url.replace("1","f")

The replace method returns a new string (which you immediately discard), so you are not actually changing anything in the column data source. You need something like:

old = data['url'][0]
data['url'] = old.replace("1","f")