简体   繁体   English

如何在Bokeh中为多选小部件实现Javascript回调

[英]How to implement a Javascript callback for a multiselect widget in Bokeh

I am new to both Bokeh and Javascript and I am trying to implement a simple multiselect widget in Bokeh. 我是Bokeh和Javascript的新手,我正在尝试在Bokeh中实现一个简单的多选小部件。 The idea is simply to display the x and y data on a scatterplot depending on the letter or letters chosen by the user (A, B, C). 这个想法只是根据用户选择的一个或多个字母(A,B,C)在散点图上显示x和y数据。 The graph should be empty before the user selects a choice. 在用户选择选项之前,图表应为空。 The problem lies with the Javascript callback: nothing happens when I select an entry with the MultiSelect widget. 问题在于Javascript回调:当我使用MultiSelect小部件选择条目时没有任何反应。 The code is below. 代码如下。

from bokeh.models import CustomJS, ColumnDataSource, MultiSelect, Column
from bokeh.plotting import figure, show
import pandas as pd

data = dict(letter = ['A','A','B','C','B','B','A','C','C','B'], 
x = [1, 2, 1, 2, 3, 2, 2, 3, 2, 3], 
y = ['10','20','10','30','10','40','10','30','10','40'])
data = pd.DataFrame(data)

data_source = ColumnDataSource(data)
source = ColumnDataSource(dict(letter = [], x = [], y = []))

plot = figure()
plot.circle('x', 'y', line_width = 2, source = source)

callback = CustomJS(args = {'source': source, 'data_source': data_source},
code = """
var data = data_source
source.data = data[cb_obj.value];
""")

multiselect = MultiSelect(title = 'Choose', value = [], options = ['A', 'B', 'C'])
multiselect.js_on_change('value', callback)

layout = Column(multiselect, plot)
show(layout)

Any ideas ? 有任何想法吗 ?

You're on the right track. 你走在正确的轨道上。 If you'd like to filter data it is generally a good idea to have a "master" data source from which to extract only the required elements as the filtered value changes. 如果您想过滤数据,通常最好有一个“主”数据源,在过滤后的值发生变化时,只能从中提取所需的元素。 I find it easiest to do this using loops (see code below). 我发现使用循环最简单(见下面的代码)。 Also, don't forget to always emit the changes to the source at the end of the callback. 此外,不要忘记在回调结束时始终发出对源的更改。

from bokeh.models import CustomJS, ColumnDataSource, MultiSelect, Column

from bokeh.plotting import figure, show
import pandas as pd

data = dict(letter = ['A','A','B','C','B','B','A','C','C','B'], 
x = [1, 2, 1, 2, 3, 2, 2, 3, 2, 3], 
y = ['10','20','10','30','10','40','10','30','10','40'])
data = pd.DataFrame(data)

data_source = ColumnDataSource(data)
source = ColumnDataSource(dict(x = [], y = []))

plot = figure()
plot.circle('x', 'y', line_width = 2, source = source)

callback = CustomJS(args = {'source': source, 'data_source': data_source},
code = """
var data = data_source.data;
var s_data = source.data;
var letter = data['letter'];
var select_vals = cb_obj.value;
var x_data = data['x'];
var y_data = data['y'];
var x = s_data['x'];
x.length = 0;
var y = s_data['y'];
y.length = 0;
for (var i = 0; i < x_data.length; i++) {
    if (select_vals.indexOf(letter[i]) >= 0) {
        x.push(x_data[i]);
        y.push(y_data[i]);
        }
}
source.change.emit();
""")

multiselect = MultiSelect(title = 'Choose', value = [], options = ['A', 'B', 'C'])
multiselect.js_on_change('value', callback)
layout = Column(multiselect, plot)
show(layout)

General comment: I - like you - only started using Bokeh recently and I'm a JS novice, too. 一般评论:我 - 像你一样 - 最近才开始使用Bokeh,我也是JS的新手。 I found the examples in the Bokeh user guide , very helpful. 我在Bokeh 用户指南中找到了这些示例,非常有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM