使用Bokeh下拉小工具/CustomJS过滤数据帧
问题描述
我必须制作一个独立的html仪表板,所以我想知道如何使用CustomJS将回调添加到bokeh下拉小部件。问题是,即使在查阅了其他关于这个主题的变化的帖子后,我仍然无法理解。如有任何帮助,我们将不胜感激!最终,我会使用下拉菜单来过滤堆叠的条形图,但我想尝试在先过滤DataTable之后自己解决这个问题。
我已经咨询了Filtering dataframe using Bokeh/Widget/Callback、Bokeh datatable filtering inconsistency、Filtering dataframe using Bokeh/Widget/Callback和Python bokeh CustomJS callback update DataTable widget。此外,我还浏览了https://docs.bokeh.org/en/1.3.4/docs/user_guide/interaction/callbacks.html#userguide-interaction-jscallbacks,
上的文档import pandas as pd
from bokeh.models.widgets import Dropdown
from bokeh.layouts import widgetbox
from bokeh.models import ColumnDataSource, DataTable, TableColumn, CustomJS
from bokeh.io import show, output_file, output_notebook, reset_output
raw_data = {'ORG': ['APPLE', 'ORANGE', 'MELON'],
'APPROVED': [5, 10, 15],
'CREATED': [1, 3, 5],
'INPROCESS': [4,2,16]}
df = pd.DataFrame(raw_data)
# create list of orgs to use later
org_l = list(df['ORG'].unique())
# create CDS for source
src = ColumnDataSource(df)
# create cols
table_columns = [TableColumn(field = Ci, title = Ci) for Ci in df.columns]
# create filtered table
filtered_df = df.loc[df['ORG']=='f']
# create CDS for filtered source
new_src = ColumnDataSource(filtered_df)
# create dropdown
dropdown = Dropdown(label="Dropdown button", button_type="warning", menu = org_l)
callback_code = """"
var data = src.data;
var new_data = new_src.data;
var f = cb_obj.value;
var list = org_l;
if var i = org_list[i] {
new_src.data = src.data
}
"""
callback=CustomJS(args=dict(dropdown = dropdown,source=src),
code=callback_code)
# create table
member_table = DataTable(source = new_src, columns = table_columns)
dropdown.js_on_change('value', callback)
show(widgetbox(dropdown, member_table))
‘
解决方案
好的,通过大量的反复试验和来自BigredDot的指针,我得到了下面的工作。
import pandas as pd
from bokeh.models.widgets import Select
from bokeh.layouts import widgetbox
from bokeh.models import ColumnDataSource, DataTable, TableColumn, CustomJS
from bokeh.io import show, output_file, output_notebook, reset_output
from bokeh.layouts import row, column, layout
raw_data = {'ORG': ['APPLE', 'ORANGE', 'MELON'],
'APPROVED': [5, 10, 15],
'CREATED': [1, 3, 5],
'INPROCESS': [4,2,16]}
df = pd.DataFrame(raw_data)
# create CDS for source
src1 = ColumnDataSource(df)
# create cols
table_columns1 = [TableColumn(field = Ci, title = Ci) for Ci in df.columns]
# original data table
data_table1 = DataTable(source=src1,
columns=table_columns, width=400, height=280)
# create empty dataframe to hold variables based on selected ORG value
df2 = pd.DataFrame({'status':['APPROVED', 'CREATED', 'INPROCESS'],
'count':[float('nan'), float('nan'), float('nan')]})
# create CDS for empty dataframe
src2 = ColumnDataSource(df2)
# create cols
table_columns2 = [TableColumn(field = Ci, title = Ci) for Ci in df2.columns]
callback = CustomJS(args=dict(src1=src1, src2=src2), code='''
var count = ['APPROVED', 'CREATED', 'INPROCESS'];
if (cb_obj.value != 'Please choose...') {
var org = src1.data['ORG'];
var ind = org.indexOf(cb_obj.value);
for (var i = 0; i < count.length; i++) {
src2.data['count'][i] = src1.data[count[i]][ind];
}
}
else {
for (var i = 0; i < status.length; i++) {
src2.data['status'][i] = undefined;
}
}
src2.change.emit();
''')
options = ['Please choose...'] + list(src1.data['ORG'])
select = Select(title='Test', value=options[0], options=options)
select.js_on_change('value', callback2)
show(column(select, data_table2))
相关文章