javascript - 如何在 Bokeh 中为多选小部件实现 Javascript 回调
问题描述
我是 Bokeh 和 Javascript 的新手,我正在尝试在 Bokeh 中实现一个简单的多选小部件。这个想法只是根据用户选择的一个或多个字母(A、B、C)在散点图上显示 x 和 y 数据。在用户选择一个选项之前,图表应该是空的。问题在于 Javascript 回调:当我使用 MultiSelect 小部件选择一个条目时没有任何反应。代码如下。
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)
有任何想法吗 ?
解决方案
你在正确的轨道上。如果您想过滤数据,通常最好有一个“主”数据源,以便在过滤值更改时仅从中提取所需元素。我发现使用循环最容易做到这一点(见下面的代码)。此外,不要忘记始终在回调结束时向源发出更改。
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)
一般评论:我 - 像你一样 - 最近才开始使用 Bokeh,我也是 JS 新手。我在 Bokeh用户指南中找到了示例,非常有帮助。
推荐阅读
- java - 使用 gradlew 和自定义 JRE 运行单元测试
- url - 使用响应式 WebClient 的 SAP OData 调用 - “/”转义
- swift - 是否有一个函数可以用来查找按下了哪个 UIButton 并返回 true 或 false?
- c++ - 在任意点检测到箭头键按下
- php - PHPDeployer:根据主机为本地任务设置变量?
- c# - 执行处理程序的子请求时出错(仅在服务器上部署的应用程序)
- c# - 在 NumericUpDown 值更改时启用 GroupBox
- azure - 函数应用部署得到 403 错误和扩展代码 01020
- typescript - 从没有“as const”的数组创建类型元组
- javascript - JavaScript replace() 方法替换错误字符