如何绑定Bokeh的Dropdown组件与柱状图实现按类别筛选数据
Bokeh下拉组件与柱状图联动实现方案
现有代码问题
- 未使用ColumnDataSource管理图表数据,直接传入静态DataFrame值,无法支持动态更新
- 未给下拉组件绑定事件回调,选中下拉项后没有对应逻辑刷新图表数据
- 下拉菜单选项存在重复值,未做去重处理
当前运行无响应的效果如下图:
修改后可运行代码
# 导入依赖库 import math import pandas as pd from bokeh.models import ColumnDataSource, Dropdown from bokeh.plotting import figure, show from bokeh.layouts import row from bokeh.resources import INLINE import bokeh.io bokeh.io.output_notebook(INLINE) # --- 数据预处理 --- # 保存原始全量数据 raw_data = data[["Rating", "Genres", "Category"]].copy() # 封装筛选+统计逻辑,支持根据选中分类返回对应数据 def get_filtered_data(selected_category=None): if selected_category: filtered = raw_data[raw_data["Category"] == selected_category] else: filtered = raw_data # 按题材分组统计评分数量 genre_view = filtered.groupby(by="Genres", as_index=False).count() genre_view = genre_view.rename(columns={"Rating": "Total Ratings"}) # 按评分数量降序排序 genre_view.sort_values(by="Total Ratings", ascending=False, inplace=True) return genre_view # 初始化默认显示全量数据 init_data = get_filtered_data() # 用ColumnDataSource管理动态数据,是Bokeh实现交互的核心 source = ColumnDataSource(init_data) # --- 下拉组件初始化 --- # 对分类做去重处理,避免重复选项 menu_list = raw_data["Category"].dropna().unique().tolist() # Bokeh下拉菜单要求选项为(显示名, 传递值)的元组格式 dropdown_menu = [(item, item) for item in menu_list] dropdown = Dropdown(label='全部分类', button_type='warning', menu=dropdown_menu) # --- 初始化柱状图 --- p = figure( title = "不同分类下评分最高的题材排行", x_range = init_data["Genres"], x_axis_label = "题材", sizing_mode = "stretch_both", y_axis_label = "评分数量" ) # 数据源绑定为上面定义的ColumnDataSource,列名对应DataFrame的字段即可 p.vbar( x = "Genres", bottom = 0, top = "Total Ratings", source = source, line_color = "black", fill_color = "#4c7bd3" ) # X轴标签45度倾斜 p.xaxis.major_label_orientation = math.pi/4 # --- 绑定下拉组件回调逻辑(Bokeh Server环境适用,notebook直接运行可选此方案) --- def dropdown_click_callback(event): # 获取选中的分类值 selected_cat = event.item # 重新筛选统计数据 new_data = get_filtered_data(selected_cat) # 更新数据源,自动触发图表刷新 source.data = new_data.to_dict(orient='list') # 更新X轴的类目范围 p.x_range.factors = new_data["Genres"].tolist() # 更新下拉按钮显示文本为当前选中分类 dropdown.label = selected_cat # 给下拉组件绑定点击事件 dropdown.on_click(dropdown_click_callback) # 渲染布局 show(row(p, dropdown))
关键修改说明
- 统一使用
ColumnDataSource作为图表的数据源,所有数据修改直接更新source的data属性即可自动触发图表刷新 - 下拉菜单先做去重处理,符合组件的参数要求
- 给下拉组件绑定点击事件回调,选中分类后自动筛选对应数据、重新统计、更新数据源和X轴类目
- 上述方案适合Bokeh Server运行,若需要在静态notebook中无服务运行,可将回调替换为
CustomJS写法,将全量数据序列化后传入JS侧做筛选即可
内容的提问来源于stack exchange,提问作者Myst
相关产品推荐
相关产品推荐

