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

基于Bokeh为堆叠条形图添加UC列CheckboxGroup筛选功能

实现Bokeh CheckboxGroup更新堆叠水平条形图的方案

嘿,我来帮你搞定这个Bokeh的交互功能!其实核心就是用CheckboxGroup组件结合JavaScript回调(CustomJS)来动态过滤数据并更新图表,下面给你一步步的具体实现方法,包含完整代码示例:

核心思路

咱们需要:

  • 用CheckboxGroup创建航司选择控件
  • 给图表的数据源绑定CustomJS回调,监听CheckboxGroup的选中变化
  • 在回调里根据选中的航司过滤原始数据,更新图表的数据源,实现实时刷新

完整代码示例

from bokeh.io import show, save
from bokeh.layouts import column
from bokeh.models import ColumnDataSource, CheckboxGroup, CustomJS
from bokeh.plotting import figure

# ---------------------- 1. 模拟你的数据集(替换成你的真实数据) ----------------------
# 数据结构:UC_Month(月份)、carrier(航司)、dep_delayed_15min_count(延误数)、on_time_count(准点数量)
data = {
    "UC_Month": ["Jan", "Jan", "Jan", "Jan", "Jan", "Feb", "Feb", "Feb", "Feb", "Feb"],
    "carrier": ["WN", "AA", "UA", "OO", "OA", "WN", "AA", "UA", "OO", "OA"],
    "dep_delayed_15min_count": [120, 90, 80, 60, 40, 130, 100, 75, 55, 35],
    "on_time_count": [480, 410, 320, 240, 160, 520, 450, 350, 260, 180]
}
original_source = ColumnDataSource(data)

# ---------------------- 2. 准备初始显示的数据源(默认显示所有航司) ----------------------
months = list(set(data["UC_Month"]))
carriers = ["WN", "AA", "UA", "OO", "OA"]

# 构建初始堆叠数据
stack_data = {"UC_Month": months}
for carrier in carriers:
    # 提取该航司的延误和准点数据
    delayed = [d for m, c, d in zip(data["UC_Month"], data["carrier"], data["dep_delayed_15min_count"]) if c == carrier]
    on_time = [t for m, c, t in zip(data["UC_Month"], data["carrier"], data["on_time_count"]) if c == carrier]
    stack_data[f"{carrier}_delayed"] = delayed
    stack_data[f"{carrier}_on_time"] = on_time

stack_source = ColumnDataSource(stack_data)

# ---------------------- 3. 创建堆叠水平条形图 ----------------------
p = figure(y_range=months, height=400, width=800, title="Flight On-Time vs Delayed by Carrier")

# 绘制堆叠水平条形:先画延误,再画准点
p.hbar_stack(
    stackers=[f"{c}_delayed" for c in carriers],
    y="UC_Month",
    height=0.8,
    color="#e45756",
    source=stack_source,
    legend_label=[f"{c} Delayed" for c in carriers]
)
p.hbar_stack(
    stackers=[f"{c}_on_time" for c in carriers],
    y="UC_Month",
    height=0.8,
    color="#4c72b0",
    source=stack_source,
    legend_label=[f"{c} On Time" for c in carriers]
)

p.yaxis.axis_label = "Month"
p.xaxis.axis_label = "Number of Flights"
p.legend.location = "top_right"
p.legend.click_policy = "hide"  # 可选:点击图例隐藏对应系列

# ---------------------- 4. 创建CheckboxGroup控件 ----------------------
checkbox = CheckboxGroup(
    labels=carriers,
    active=list(range(len(carriers))),  # 默认全部选中
    width=200
)

# ---------------------- 5. 编写CustomJS回调函数 ----------------------
callback = CustomJS(args=dict(original_source=original_source, stack_source=stack_source, checkbox=checkbox, carriers=carriers), code="""
    // 获取选中的航司索引
    const active_indices = checkbox.active;
    const selected_carriers = active_indices.map(i => carriers[i]);
    
    // 如果没有选中任何航司,默认选中全部
    const target_carriers = selected_carriers.length > 0 ? selected_carriers : carriers;
    
    // 从原始数据中提取月份(保持顺序)
    const months = original_source.data.UC_Month.filter((m, idx) => idx % carriers.length === 0);
    
    // 初始化新的堆叠数据
    const new_data = {UC_Month: months};
    
    // 遍历每个选中的航司,提取对应的数据
    target_carriers.forEach(carrier => {
        const delayed = [];
        const on_time = [];
        
        months.forEach(month => {
            // 找到该月份该航司的数据
            const idx = original_source.data.UC_Month.indexOf(month) + carriers.indexOf(carrier);
            delayed.push(original_source.data.dep_delayed_15min_count[idx]);
            on_time.push(original_source.data.on_time_count[idx]);
        });
        
        new_data[`${carrier}_delayed`] = delayed;
        new_data[`${carrier}_on_time`] = on_time;
    });
    
    // 更新堆叠图的数据源
    stack_source.data = new_data;
""")

# 给CheckboxGroup绑定回调
checkbox.js_on_change('active', callback)

# ---------------------- 6. 布局并输出HTML ----------------------
layout = column(checkbox, p)
# 保存为HTML文件
save(layout, filename="flight_delay_chart.html")
# 或者直接在浏览器显示
# show(layout)

关键部分解释

  1. 数据源处理:

    • original_source存储原始的全量数据,方便回调里过滤
    • stack_source是图表直接使用的数据源,结构适配堆叠条形图的要求
  2. CheckboxGroup配置:

    • labels设置航司选项,active默认全部选中,符合初始显示所有数据的需求
  3. CustomJS回调逻辑:

    • 监听CheckboxGroup的active属性变化(即选中状态改变)
    • 过滤出选中的航司,处理空选择的边界情况(默认选全部)
    • 从原始数据中提取对应航司的准点/延误数据,重新构建堆叠图需要的数据源结构
    • 更新stack_source的数据,图表会自动刷新
  4. 堆叠图绘制:

    • 用hbar_stack方法快速创建水平堆叠条形,分别对应延误和准点数据,颜色区分明显

这样你运行代码后生成的HTML页面,就能通过勾选CheckboxGroup里的航司选项,实时更新堆叠条形图啦!

内容的提问来源于stack exchange,提问作者A2N15

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 21:57:40