Bokeh 中的 CheckboxGroup 用于绘制附加图
CheckboxGroup in Bokeh to plot additive plots
我想使用复选框组来表示线性相加的源。这个想法是让用户能够打开或关闭多个不同类型的源来显示具有附加值的图。
我实现了一个下拉版本,其中数据具有不同的组合作为数据框的列,因此代码的 CustomJS 部分如下:
callback = CustomJS(args={'source':source},code="""
// print the selectd value of the select widget -
// this is printed in the browser console.
// cb_obj is the callback object, in this case the select
// widget. cb_obj.value is the selected value.
console.log(' changed selected option', cb_obj.value);
// create a new variable for the data of the column data source
// this is linked to the plot
var data = source.data;
// allocate the selected column to the field for the y values
data['A1'] = data[cb_obj.value];
// register the change - this is required to process the change in
// the y values
source.change.emit();
""")
我不太了解Javascript。有没有办法只给出一个数据框如下:
Wave A B C
340 77 70 15
341 80 73 15
342 83 76 16
343 86 78 17
并且具有复选框组按钮,如果用户选择 'A' 和 'C',则绘图将更改为 Wave vs. A+C 的绘图,反之亦然以删除选择。
我发现了一个类似的问题,但它只是 shows/hides 图,并没有改变数据:
我在实际数据中有太多选择,无法手动分配组合。
是的,您可以使用 CheckboxGroup 实现此目的 - 您可以使用 CheckboxGroup 的 active
属性 select 将正确的列添加到组合图中。
以下是您提供的数据的完整示例:
from bokeh.io import output_file, show
from bokeh.plotting import figure
from bokeh.layouts import layout, widgetbox
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import CheckboxGroup
import pandas as pd
output_file('additive_checkbox.html')
names = ['Wave', 'A', 'B', 'C']
rows = [(340, 77, 70, 15),
(341, 80, 73, 15),
(342, 83, 76, 16),
(343, 86, 78, 17)]
data = pd.DataFrame(rows, columns=names)
data['combined'] = None
source = ColumnDataSource(data)
callback = CustomJS(args=dict(source=source), code="""
const labels = cb_obj.labels;
const active = cb_obj.active;
const data = source.data;
const sourceLen = data.combined.length;
const combined = Array(sourceLen).fill(undefined);
if (active.length > 0) {
const selectedColumns = labels.filter((val, ind) => active.includes(ind));
for(let i = 0; i < sourceLen; i++) {
let sum = 0;
for(col of selectedColumns){
sum += data[col][i];
}
combined[i] = sum;
}
}
data.combined=combined;
source.change.emit();
""")
checkbox_group = CheckboxGroup(labels=names[1:], active=[], callback=callback)
p = figure(width=400, height=400)
p.line(x='Wave', y='combined', source=source)
show(layout([[widgetbox(checkbox_group)], [p]]))
我想使用复选框组来表示线性相加的源。这个想法是让用户能够打开或关闭多个不同类型的源来显示具有附加值的图。
我实现了一个下拉版本,其中数据具有不同的组合作为数据框的列,因此代码的 CustomJS 部分如下:
callback = CustomJS(args={'source':source},code="""
// print the selectd value of the select widget -
// this is printed in the browser console.
// cb_obj is the callback object, in this case the select
// widget. cb_obj.value is the selected value.
console.log(' changed selected option', cb_obj.value);
// create a new variable for the data of the column data source
// this is linked to the plot
var data = source.data;
// allocate the selected column to the field for the y values
data['A1'] = data[cb_obj.value];
// register the change - this is required to process the change in
// the y values
source.change.emit();
""")
我不太了解Javascript。有没有办法只给出一个数据框如下:
Wave A B C
340 77 70 15
341 80 73 15
342 83 76 16
343 86 78 17
并且具有复选框组按钮,如果用户选择 'A' 和 'C',则绘图将更改为 Wave vs. A+C 的绘图,反之亦然以删除选择。
我发现了一个类似的问题,但它只是 shows/hides 图,并没有改变数据:
我在实际数据中有太多选择,无法手动分配组合。
是的,您可以使用 CheckboxGroup 实现此目的 - 您可以使用 CheckboxGroup 的 active
属性 select 将正确的列添加到组合图中。
以下是您提供的数据的完整示例:
from bokeh.io import output_file, show
from bokeh.plotting import figure
from bokeh.layouts import layout, widgetbox
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.models.widgets import CheckboxGroup
import pandas as pd
output_file('additive_checkbox.html')
names = ['Wave', 'A', 'B', 'C']
rows = [(340, 77, 70, 15),
(341, 80, 73, 15),
(342, 83, 76, 16),
(343, 86, 78, 17)]
data = pd.DataFrame(rows, columns=names)
data['combined'] = None
source = ColumnDataSource(data)
callback = CustomJS(args=dict(source=source), code="""
const labels = cb_obj.labels;
const active = cb_obj.active;
const data = source.data;
const sourceLen = data.combined.length;
const combined = Array(sourceLen).fill(undefined);
if (active.length > 0) {
const selectedColumns = labels.filter((val, ind) => active.includes(ind));
for(let i = 0; i < sourceLen; i++) {
let sum = 0;
for(col of selectedColumns){
sum += data[col][i];
}
combined[i] = sum;
}
}
data.combined=combined;
source.change.emit();
""")
checkbox_group = CheckboxGroup(labels=names[1:], active=[], callback=callback)
p = figure(width=400, height=400)
p.line(x='Wave', y='combined', source=source)
show(layout([[widgetbox(checkbox_group)], [p]]))