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

基于Bokeh实现任意规模矩阵时序图及MultiChoice+CustomJS动态切换

解决方案

核心思路

  • 不硬编码子图索引,而是把每个子图对应的数据源、目标分量信息绑定在一起,通过JavaScript遍历所有绑定对象实现批量更新。
  • 利用Bokeh的参数传递,将所有子图的更新所需信息打包成数组,在CustomJS中直接遍历处理,适配任意规模的矩阵。

代码实现步骤

1. 生成子图矩阵与信息集合

假设你的order_dict是Python字典,键为分量名称,值对应时序数据的索引。遍历矩阵每个位置创建子图,同时收集每个子图的关键更新信息:

from bokeh.layouts import gridplot
from bokeh.models import ColumnDataSource, MultiChoice, CustomJS
from bokeh.plotting import figure

# 示例配置:替换成你的实际数据与矩阵规模
rows, cols = 3, 4
order_dict = {"x": 0, "y": 1, "z": 2}
# vec_ts:你的向量时序矩阵,shape=(rows, cols, 分量数, 时间步长)

subplots = []
plot_update_info = []

for i in range(rows):
    row_plots = []
    for j in range(cols):
        # 提取当前位置的向量时序数据
        current_ts = vec_ts[i, j]
        # 初始化数据源,默认展示第一个分量
        source = ColumnDataSource(data={
            "time": list(range(len(current_ts[0]))),
            "value": current_ts[order_dict["x"]]
        })
        # 创建子图
        p = figure(width=200, height=150, title=f"({i},{j})")
        line_renderer = p.line(x="time", y="value", source=source)
        row_plots.append(p)
        # 记录该子图的更新依赖信息
        plot_update_info.append({
            "source": source,
            "raw_data": current_ts.tolist(),  # 转成JS可识别的列表格式
        })
    subplots.append(row_plots)

# 生成网格布局
grid = gridplot(subplots)

2. 实现MultiChoice与批量更新回调

在CustomJS中直接遍历plot_update_info数组,根据选中分量批量更新所有子图:

# 创建分量选择组件
multi_choice = MultiChoice(options=list(order_dict.keys()), value=["x"])

# 编写JS回调逻辑
callback = CustomJS(args={
    "update_info": plot_update_info,
    "component_map": order_dict,
    "choice_widget": multi_choice
}, code="""
    // 获取当前选中的分量,无选中时默认取第一个分量
    const selected_comp = choice_widget.value.length > 0 ? choice_widget.value[0] : Object.keys(component_map)[0];
    const comp_index = component_map[selected_comp];
    
    // 遍历所有子图信息,批量更新数据源
    update_info.forEach(item => {
        // 替换数据源中的value字段为选中分量的时序数据
        item.source.data.value = item.raw_data[comp_index];
        // 触发数据源变更,刷新子图
        item.source.change.emit();
    });
""")

# 绑定组件的value变化事件与回调
multi_choice.js_on_change("value", callback)

关键细节说明

  • 动态适配矩阵规模:通过Python循环收集所有子图的更新信息,JS中用forEach遍历处理,不管矩阵行数、列数怎么变,都无需修改JS代码。
  • 数据传递兼容性:将Python中的时序数据转成list传入JS,确保JavaScript能直接读取使用。
  • 高效批量更新:一次遍历完成所有子图的数据源更新,避免重复编写硬编码的索引循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:01:19