基于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
相关产品推荐
相关产品推荐

