You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何绑定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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 20:06:10