繁体   English   中英

为bokeh中的复选框实现JavaScript回调?

[英]Implementing JavaScript callback for checkboxes in bokeh?

简短版本:带有JS回调的散景复选框,用于绘制数据框的子集?

更长的版本: 这里的答案给出了多选的一个很好的解释,但我想对复选框做同样的事情。 我的所有数据都在一个pandas数据帧中,我使用复选框选择该数据帧的位用于绘图。 我相信,对于复选框,它与cb_obj.active但我不确定如何让它工作。 特别是我的绘图包括彩色矩形和文本,所有信息的位置,文本,颜色都取自我的数据框。 而且我不知道在回调中必须做多少绘图,以及外面有多少。

据我所知,回调调用函数来进行实际的绘图。

我知道我应该给出一个最小的例子,但我想不出如何简化我的代码...所以我现在真正想要的是使用带有JavaScript回调的复选框绘制子集的示例一个数据帧。 有人必须这样做,但我还没有找到一个例子! 谢谢。

这是一个例子:

from bokeh.plotting import figure, show, output_notebook
from bokeh.models import Slider, CheckboxGroup, CustomJS, ColumnDataSource, CDSView
from bokeh.models.filters import CustomJSFilter
from bokeh.layouts import row
from bokeh.transform import factor_cmap
from bokeh.palettes import Category10_10
output_notebook()

您可以使用CustomJSFilter来计算要显示的行的CustomJSFilter

from bokeh.sampledata import iris
source = ColumnDataSource(data=iris.flowers)
species = iris.flowers.species.unique().tolist()
checkboxes = CheckboxGroup(labels=species, active=list(range(len(species))))
fig = figure()
filter =  CustomJSFilter(code="""
let selected = checkboxes.active.map(i=>checkboxes.labels[i]);
let indices = [];
let column = source.data.species;
for(let i=0; i<column.length; i++){
    if(selected.includes(column[i])){
        indices.push(i);
    }
}
return indices;
""", args=dict(checkboxes=checkboxes, source=source))

checkboxes.js_on_change("active", CustomJS(code="source.change.emit();", args=dict(source=source)))

fig.scatter("sepal_length", "sepal_width", 
            color=factor_cmap("species", Category10_10, species),
            source=source, view=CDSView(source=source, filters=[filter]))
show(row(checkboxes, fig))

在此输入图像描述

以下是我提到的MultiSelect答案的改编版本:

from bokeh.models import CustomJS, ColumnDataSource, 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.active.map(x => cb_obj.labels[x]);
console.log(select_vals);
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();
console.log("callback completed");
""")

chkbxgrp = CheckboxGroup(labels = ['A', 'B', 'C'], active=[])
chkbxgrp.js_on_change('active', callback)
layout = Column(chkbxgrp, plot)
show(layout)

备注:

  • 回调在Internet Explorer中不起作用,因为它使用IE不支持的箭头功能。 如果这是一个问题,您需要使用箭头函数之外的其他内容进行映射
  • 正如用户bigreddot在您提到的答案中所评论的,这也可以使用CDSView使用自定义过滤器来完成,因为GroupFilter不支持多个值

暂无
暂无

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

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