使用 Bokeh Slider 浏览图像

3
我正在尝试使用滑块无缝传递大量科学数据。
我开始使用Bokeh,对JavaScript几乎没有了解。我试图设置第一种方法,以便能够滑动两个图像,但我无法刷新图像。
假设我的文件夹中有1.png和2.png。
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)

我从Bokeh Widget Docworking with images in bokeh中引用了一些示例。
我的想法是,通过回调img片段,滑块将修改包含url(即要加载的图像的名称)的源。 我认为,目前简单地访问源中的字符串,并通过滑块的当前值进行替换(因此当滑块从1到2时,它应该跳过1.png到2.png),就可以解决问题。
然而,什么都没有改变。 我怀疑在Javascript片段中做错了什么。
感谢任何反馈
编辑:根据@bigreddot的建议,我编辑了代码,但现在当位置“2”滑动时,滑块只显示一个空图形。 编辑2:在我的下面的答案中解决了这个问题
4个回答

2

@bigreddot的答案是正确的,但是变量f是一个数字,所以在替换时,我需要写成f.toString(10)。 实现我想要的功能的代码:

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)

1
这个问题是:
url = data['url'][0]
url.replace("1","f")
< p > replace 方法返回一个新的字符串(你立即丢弃),因此你实际上没有改变列数据源中的任何内容。你需要像这样的东西:

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

1
我创建了一个示例,其中图像根据滑块值更改。 如果滑块值为1,则应用程序将显示map-marker.png图像,如果值为2,则应用程序将显示google_logo.png图像。
通过Div的帮助,您可以轻松完成此任务。

map-marker.png map-marker.png

google_logo.png google_logo.png

步骤:

  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 工作中

在 bokeh 版本 0.12.13 上测试通过


1
作为这个解决方案的补充,logo.text可以被动态更改,将其视为常规的Python字符串,例如:"""<img src="static/image/{}.png" alt="logo">""".format(file_name)(在Python 3.7.3和bokeh 1.2.0中测试通过)。 - Arturo Moncada-Torres

0
另一个选项是预先创建一个包含所有图像URL的数据源,并使用滑块选择正确的图像。
给定图像名称:
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

你可以做:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接