Sliding through images with Bokeh Slider

有些话、适合烂在心里 提交于 2019-12-06 01:51:20

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")

@bigreddot answer is correct, but var f is a number, so in the replace, I need to write f.toString(10). Code that does what I want:

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.toString(10))
    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 have created a sample example where image changes as per the slider value. If slider value is 1 then app will display map-marker.png image and if value is 2 then app will display google_logo.png image.

With the help of Div you can do this task very easily.

map-marker.png

google_logo.png

Steps:

  1. Create a folder named 'image' in /usr/local/lib/python2.7/dist-packages/bokeh/server/static this path
  2. After creating folder in above mentioned location copy google_logo.png and map-marker.png images to /usr/local/lib/python2.7/dist-packages/bokeh/server/static/image this location. And save the following code as app.py and run it using bokeh serve app.py --show command.

    from bokeh.io import curdoc
    from bokeh.layouts import row
    from bokeh.models.widgets import Slider, Div
    
    def change_img(attr, old, new):
        if slider.value == 1:
            logo.text = """<img src="static/image/map-marker.png"  alt="logo">"""
        else:
            logo.text = """<img src="static/image/google_logo.png"  alt="logo">"""
    
    slider = Slider(start=1, end=2, value=1, title="image number")
    slider.on_change('value', change_img)
    logo = Div(text="""<img src="static/image/logo.png"  alt="logo">""")
    
    curdoc().add_root(row(slider,logo))
    curdoc().title = "Image Demo"
    

app.py working

tested on bokeh version 0.12.13

Another option is to create in advance a data source with all the image urls and use the slider to select the correct image.

Given the image names:

import pandas as pd
imgs = ['1.png', '2.png', '3.png']
df = pd.DataFrame(imgs, columns=['imgs'])
print(df.head())

     imgs
0   1.png
1   2.png
2   3.png

You can do:

from bokeh.layouts import layout
from bokeh.plotting import figure, show
from bokeh.models import CustomJS, Slider, ColumnDataSource

source = ColumnDataSource(df)
p = figure(x_range=(0,1), y_range=(0,1))
im = p.image_url(url=[source.data['imgs'][0]], x=0, y=1, w=1, h=1)

cb = CustomJS(args=dict(im=im, source=source), code="""
    im.data_source.data['url'] = [source.data['imgs'][cb_obj.value]];
    im.data_source.change.emit();
""")
slider = Slider(start=0, end=2, value=0, step=1, title="image number", callback=cb)
show(layout([slider, p]))
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!