javascript - Python Bokeh 和 Javascript 中的多个过滤器
问题描述
这建立在我之前的问题(在 Python 的 Bokeh 中使用 Javascript 回调过滤数据)已成功回答并更进一步。
当我尝试在 Python 的 Bokeh 中使用多个过滤器过滤我的图时,该函数返回一个空图。
我找不到与使用一个过滤器的工作解决方案的任何概念差异,因此希望有任何提示。
下面是一个可重现的例子:
# Packages
import bokeh.events as bev
import bokeh.layouts as bla
import bokeh.models as bmo
import numpy as np
import pandas as pd
from bokeh.plotting import figure, output_file, show
# Data
data = pd.DataFrame(
data=np.array(
[
[1, 1, 'a', 'c', 0.5],
[2, 2, 'a', 'c', 0.5],
[3, 3, 'a', 'd', 0.75],
[4, 4, 'b', 'd', 1],
[5, 5, 'b', 'd', 2]
]
),
columns=['x', 'y', 'category 1', 'category 2', 'other information']
)
# Setup
output_file('dashboard.html')
source = bmo.ColumnDataSource(data)
# Define dropdown options
dropdown_options1 = [
('All', 'All'), None
] + [(cat, cat)
for i, cat in enumerate(sorted(data['category 1'].unique()), 2)
]
dropdown_options2 = [
('All', 'All'), None
] + [(cat, cat)
for i, cat in enumerate(sorted(data['category 2'].unique()), 2)
]
# Generate dropdown widget
dropdown1 = bmo.Dropdown(label='Category1', button_type='default', menu=dropdown_options1)
dropdown2 = bmo.Dropdown(label='Category2', button_type='default', menu=dropdown_options2)
filtered_data = bmo.ColumnDataSource(data)
# Callback
callback = bmo.CustomJS(
args = dict(unfiltered_data = source, filtered_data = filtered_data, dropdown1 = dropdown1 , dropdown2 = dropdown2 ),
code = """
var data = unfiltered_data.data;
var ind = dropdown1.item;
var ctr = dropdown2.item;
function generateNewDataObject(oldDataObject){
var newDataObject = {}
for (var key of Object.keys(oldDataObject)){
newDataObject[key] = [];
}
return newDataObject
}
function addRowToAccumulator(accumulator, dataObject, index) {
for (var key of Object.keys(dataObject)){
accumulator[key][index] = dataObject[key][index];
}
return accumulator;
}
if (ind === 'All' && ctr === 'All'){
data = unfiltered_data.data;
} else if (ctr === 'All') {
var new_data = generateNewDataObject(data);
for (var i = 0; i <= unfiltered_data.data['category 1'].length; i++){
if (unfiltered_data.data['category 1'][i] == ind) {
new_data = addRowToAccumulator(new_data, unfiltered_data.data, i);
}
}
data = new_data;
} else if (ind === 'All'){
var new_data = generateNewDataObject(data);
for (var i = 0; i <= unfiltered_data.data['category 2'].length; i++){
if (unfiltered_data.data['category 2'][i] == ctr) {
new_data = addRowToAccumulator(new_data, unfiltered_data.data, i);
}
}
data = new_data;
} else {
var new_data = generateNewDataObject(data);
for (var i = 0; i <= unfiltered_data.data['category 1'].length; i++){
if (unfiltered_data.data['category 2'][i] == ctr && unfiltered_data.data['category 1'][i] == ind) {
new_data = addRowToAccumulator(new_data, unfiltered_data.data, i);
}
}
data = new_data;
}
filtered_data.data = data;
filtered_data.change.emit();
"""
)
# Link actions
dropdown1.js_on_event(bev.MenuItemClick, callback)
dropdown2.js_on_event(bev.MenuItemClick, callback)
# Plot
p1 = figure(plot_width=800, plot_height=530, title=None)
p1.scatter(x='x', y='y', source=filtered_data)
show(bla.column(bla.row(dropdown1, dropdown2), p1))
我尝试使用不同的方法(和)访问下拉列表的值.item
,但没有任何成功。.value
.text
感谢您的支持,奥利弗
解决方案
Dropdown 是一个单击事件,因此信息仅在事件中,而不是在小部件本身的任何属性上(如果您愿意,也许Select
小部件会比 更好的选择Dropdown
)。文档中有一个示例显示了如何访问事件中的项目:
dropdown = Dropdown(label="Dropdown button", menu=menu)
dropdown.js_on_event(
"menu_item_click",
CustomJS(code="console.log('dropdown: ' + this.item")
)
推荐阅读
- scilab - Runge-Kutta 二阶,波变换,求解保留方程*
- jquery - 基础下拉菜单不工作在角度
- angularjs - 显示和隐藏在带有“dirPagination”(AngularJS)的 ng-repeat 中
- php - Laravel 从上传中获取保存文件的路径
- wordpress - wordpress 奇怪地翻译了字段
- java - 课堂上的情况?
- php - 同时插入数据和检索主键。通过 1 提交 只有 PHP、MYSQL
- javascript - 如何替换 setTimeout 函数?
- javascript - 在第二个下拉菜单(jQuery)中过滤结果时创建“所有”数据类别
- javascript - 从 Odata 格式化/解析时间