使用散景的交互式滑块 [英] Interactive Slider using Bokeh

查看:89
本文介绍了使用散景的交互式滑块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用散景交互式滑块来修改绘图的内容,类似示例这里。我有两个嵌套列表 x y

I'm trying to use a bokeh interactive slider to modify the contents of a plot, similar the example here. I have a two nested lists x and y.

我只想让滑块更改要绘制的列表的索引。即如果滑块索引= 0,则绘制 x [0] vs y [0] ,如果滑块索引是1,绘图 x [1] vs y [1] 等...

I simply want the slider to change the index of the lists to plot. i.e. If the slider index = 0, then plot x[0] vs y[0], if the slider index is 1, plot x[1] vs y[1], etc...

文档示例动态计算新数据,这对于我需要使用的数据是不可行的。

The documentation example computes the new data on the fly, which is not feasible for the data that I need to work with.

当我运行下面的代码时,情节中没有任何内容......我不知道javascript,所以我猜这就是我要去的地方错误。

When I run the code below, nothing shows up in the plot... I don't know javascript, so I'm guessing this is where I'm going wrong.

我正在运行Python 3.5和Bokeh 0.12。这都是在一个jupyter笔记本中运行。

I'm running Python 3.5 and Bokeh 0.12. This is all run within a jupyter-notebook.

import numpy as np
from bokeh.layouts import row
from bokeh.models import CustomJS, ColumnDataSource, Slider
from bokeh.plotting import Figure, show
from bokeh.io import output_notebook
from bokeh.resources import INLINE
output_notebook(INLINE)

x = [[x*0.05 for x in range(0, 500)],
     [x*0.05 for x in range(0, 500)]]

y = [np.sin(x[0]), 
     np.cos(x[1])]

source = ColumnDataSource(data=dict(x=x, y=y))

plot = Figure(plot_width=400, plot_height=400)
plot.line('x'[0], 'y'[0], source=source, line_width=3, line_alpha=0.6)

callback = CustomJS(args=dict(source=source), code="""
        var data = source.get('data');
        var f = cb_obj.get('value');
        x = data['x'][f];
        y = data['y'][f];
        source.trigger('change');
    """)

slider = Slider(start=0, end=1, value=0, step=1, title="index", callback=callback)
layout = row(plot, slider)
show(layout)


推荐答案

而不是使用滑块更改数据的索引绘制后,您可以定义两个 ColumnDataSource s: source_visible source_available ,其中第一个包含当前在图中显示的数据,第二个包含我们可以根据网页上的用户选择在 CustomJS 回调中对数据进行采样的数据存储库:

Instead of having a slider changing the index of the data to be plotted, you could define two ColumnDataSources: source_visible and source_available where the first one holds the data that is currently being shown in the plot and the second one acts as a data repository from where we can sample data in CustomJS callback based on user selection on the web page:

import numpy as np
from bokeh.layouts import row
from bokeh.models import ColumnDataSource, Slider, CustomJS
from bokeh.plotting import Figure, show

# Define data
x = [x*0.05 for x in range(0, 500)]
trigonometric_functions = {
    '0': np.sin(x),
    '1': np.cos(x),
    '2': np.tan(x),
    '3': np.arctan(x)}
initial_function = '0'

# Wrap the data in two ColumnDataSources
source_visible = ColumnDataSource(data=dict(
    x=x, y=trigonometric_functions[initial_function]))
source_available = ColumnDataSource(data=trigonometric_functions)

# Define plot elements
plot = Figure(plot_width=400, plot_height=400)
plot.line('x', 'y', source=source_visible, line_width=3, line_alpha=0.6)
slider = Slider(title='Trigonometric function',
                value=int(initial_function),
                start=np.min([int(i) for i in trigonometric_functions.keys()]),
                end=np.max([int(i) for i in trigonometric_functions.keys()]),
                step=1)

# Define CustomJS callback, which updates the plot based on selected function
# by updating the source_visible ColumnDataSource.
slider.callback = CustomJS(
    args=dict(source_visible=source_visible,
              source_available=source_available), code="""
        var selected_function = cb_obj.value;
        // Get the data from the data sources
        var data_visible = source_visible.data;
        var data_available = source_available.data;
        // Change y-axis data according to the selected value
        data_visible.y = data_available[selected_function];
        // Update the plot
        source_visible.change.emit();
    """)

layout = row(plot, slider)
show(layout)

请记住,如果您的数据很大,可能需要一段时间才能将其全部发送到客户端的浏览器。

Keep in mind that if your data is large, it might take a while to send it all at once to the client's browser.

这篇关于使用散景的交互式滑块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆