javascript - 如何根据 Bokeh 中先前的多选选择向绘图添加参考曲线
问题描述
我是 Bokeh 的新手,我正在尝试实现一个复选框小部件,该小部件将根据用户之前的多选选择将单个参考曲线添加到绘图中。例如,如果用户在多选小部件中选择 A,则在使用复选框小部件时会出现曲线 A。如果用户在多选小部件中选择 B,则在使用复选框小部件时会出现曲线 B。只有一个名为“添加参考曲线”的复选框。现在,复选框小部件不太可能工作,因为我在使用 CustomJS 时遇到了困难。我的代码如下。有任何想法吗 ?
from bokeh.models import CustomJS, ColumnDataSource, MultiSelect, CheckboxGroup, 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)
# Toggle reference curves on/off
## Dummy data for plotting lines testing
x = list(range(10))
A = [ a**1.5 for a in x]
B = [ a**1.6 for a in x]
C = [ a**1.7 for a in x]
curve_A = plot.line(x, A, color='red')
curve_B = plot.line(x, B, color='red')
curve_C = plot.line(x, C, color='red')
curve_A.visible = False
curve_B.visible = False
curve_C.visible = False
curve_checkbox = CheckboxGroup(labels=["Add reference curve",], active=[])
curve_checkbox.callback = CustomJS(args=dict(A=A, B=B, C=C, source=source, curve_checkbox=curve_checkbox),
code="""
curve_A.visible = 0 in checkbox.active;
""")
layout = Column(multiselect, curve_checkbox, plot)
show(layout)
解决方案
试试下面的代码:
curve_checkbox.callback = CustomJS(args=dict(curve_A=curve_A,
curve_B=curve_B,
curve_C=curve_C,
source=source,
checkbox=multiselect),
code="""
let checked = cb_obj.active.length > 0
curve_A.visible = checkbox.value.indexOf("A") >= 0 && checked;
curve_B.visible = checkbox.value.indexOf("B") >= 0 && checked;
curve_C.visible = checkbox.value.indexOf("C") >= 0 && checked;
""")
推荐阅读
- devops - 不使用容器技术从 Nomad 登录到 ELK
- authentication - Google Cloud Run - 了解对最终用户进行身份验证
- python - 批处理文件运行时Python找不到文件夹
- reactjs - React hooks 应用程序适用于以下静态数据,但在迭代真实数据时出错
- php - PHP - register_shutdown_function 和文件资源
- java - springboot jpa 实体关系映射
- php - PHP - 从 XML 内容中获取值
- php - Laravel 8 的 @include 问题和来自控制器的变量
- node.js - cookie-session 未显示在浏览器 Cookie 上
- c++ - 为什么我们需要 std::initializer_list 的私有构造函数?