python - Python Bokeh - 使用选择小部件和交互式图例的交互式绘图 - 空 html 文件
问题描述
我在使用 Bokeh 时遇到了一些问题。“类别”上有一个过滤器,因此情节应该随着变化而更新。此外,该情节有一个互动图例。
代码一定有问题。我在 jupyter 笔记本中收到错误“BAD-COLUMN_NAME”,但可能也存在问题,并且 html 文件为空。拜托,我在这里需要一些帮助。谢谢!
# Perform necessary imports
import pandas as pd
from bokeh.io import output_file, show
from bokeh.plotting import figure
from bokeh.models import CustomJS, HoverTool, ColumnDataSource, Select
from bokeh.palettes import Category20_20
from bokeh.layouts import layout, widgetbox, gridplot
#Dataframe
df = pd.DataFrame({'Reg': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
'Category': ['Cat1', 'Cat1', 'Cat1', 'Cat2', 'Cat2', 'Cat2', 'Cat3', 'Cat3', 'Cat3', 'Cat3'],
'X': ['751', '673', '542', '762', '624', '536', '845', '626', '876', '233'],
'Y': ['458', '316', '287', '303', '297', '564', '278', '834', '234', '623'],
'Size': ['5', '9', '5', '8', '10', '22', '23', '12', '9', '20'],
'User': ['u1', 'u2', 'u3', 'u1', 'u2', 'u3', 'u1', 'u2', 'u3', 'u3']
})
# Make the ColumnDataSource
source = ColumnDataSource(data=dict(Reg=df['Reg'], Category=df['Category'], x=df['X'], y=df['Y'], Size=df['Size'], User=df['User']))
filteredSource = ColumnDataSource(data=dict(Reg=[], Category=[], x=[], y=[], Size=[], User=[]))
#Create widget
category = list(set(df['Category']))
category.sort()
category_select = Select(title="Category:", value=category[0], options=category)
#Callback
callback = CustomJS(args=dict(source=source, filteredSource=filteredSource,
category_select=category_select), code="""
const data = source.data;
var f = cb_obj.value;
const df2 = filteredSource.data;
df2['category']=[]
for(i = 0; i < data['category'].length;i++){
if(data['category'][i]==f){
df2['category'].push(data['category'][i])
}
}
filteredSource.change.emit()
""")
category_select.js_on_change('value', callback)
# Create the figure: p1
p1 = figure(x_axis_label='x)', y_axis_label='y',
plot_width=450, plot_height=450, tools=['box_select', HoverTool(tooltips='Size: @size')])
# Add a circle glyph to p1
users=list(set(df['User']))
for name, color in zip(users, Category20_20):
user_df = df[df['User'] == name]
p1.circle(x='X', y='Y', size='Size',
color=color, alpha=0.8, source=filteredSource, legend=name)
p1.legend.location = "top_right"
p1.legend.click_policy="hide"
#layout
layout = gridplot([widgetbox(category_select), p1], ncols=2, sizing_mode='scale_both')
show(layout)
解决方案
列名中的字符大小写不一致。您使用例如x
和X
。您必须坚持使用一种变体并在任何地方使用它——在数据源中、在创建字形渲染器时的列规范中、在CustomJS
代码中等等。
另外,你的CustomJS
代码是错误的。i = 0
将导致错误 - 您应该let i = 0
改用。而且您还只更新Category
列,而您必须更新所有列以确保它们具有相同的长度。
作为旁注,从这个和另一个问题来看,您可能会发现此文档部分非常有用:https ://docs.bokeh.org/en/latest/docs/user_guide/data.html#filtering-data 。那里描述的方法有助于防止编写 JS 代码和不必要的数据搅动。这里和 Bokeh's Discourse 上有多个示例。
推荐阅读
- javascript - 如何在 Gmail 中运行的 Chrome 扩展程序中添加第三方脚本以开发 @提及功能
- .net - .NET dll 在 MATLAB 中调用
- python - np.random.rand Python 的等效代码
- android - onBindViewHolder 只执行第一个 ViewHolder
- c - 程序编译,但收到不正确的答案 - C 中的辛普森规则集成
- cassandra - Cassandra 的 JMX 指标 TombstoneScannedHistogram RecentValues 是什么意思?
- react-native - 使用 DefaultTask 设置 gradle 插件以实例化呈现 react-native 的类
- r - R:将行转换为列并将值分配给相应的列
- node.js - 如何处理 node.js 上没有返回数据的 sqlite3
- java - 如何通过索引选择随机元素?