Bokeh:CustomJS回调后major_label_overrides未更新问题求助
问题解决:Bokeh筛选后Y轴
major_label_overrides不生效 问题拆解
- 筛选数据后图表元素正常更新,但Y轴的
major_label_overrides未同步更新,导致标签显示不符合预期 - 浏览器控制台的
TypeError: 无法在严格模式下访问'caller'是Bokeh 3.2.x版本的内部兼容性问题,通常不影响核心功能,但可通过版本升级消除
核心修复思路
major_label_overrides是静态配置项,不会随数据源自动更新,必须在筛选回调中手动同步更新该属性,使其与筛选后的新数据匹配。以下分两种常用场景给出实现代码:
1. Bokeh Server环境(Python回调)
如果是基于Bokeh Server的交互式应用,在下拉框的回调函数中同时更新数据源和Y轴标签映射:
from bokeh.models import Select, ColumnDataSource from bokeh.plotting import figure, curdoc # 初始数据与标签映射 original_data = {'x': [1,2,3], 'y': [0,1,2], 'names': ['Bob', 'Joe', 'Guy']} original_y_mapping = {0: 'Bob', 1: 'Joe', 2: 'Guy'} # 更新后的数据与标签映射 updated_data = {'x': [1,2], 'y': [0,1], 'names': ['Joe_updated', 'Guy_updated']} updated_y_mapping = {0: 'Joe_updated', 1: 'Guy_updated'} source = ColumnDataSource(data=original_data) p = figure(y_range=(0,2)) p.circle(x='x', y='y', source=source) p.yaxis.major_label_overrides = original_y_mapping select = Select(title="筛选版本", options=["原始", "更新版"]) def update_plot(attr, old, new): if new == "更新版": source.data = updated_data # 同步更新Y轴标签映射和范围 p.yaxis.major_label_overrides = updated_y_mapping p.y_range.start, p.y_range.end = min(updated_data['y']), max(updated_data['y']) else: source.data = original_data p.yaxis.major_label_overrides = original_y_mapping p.y_range.start, p.y_range.end = 0, 2 select.on_change('value', update_plot) curdoc().add_root(p) curdoc().add_root(select)
2. 静态HTML环境(CustomJS前端回调)
如果是生成静态HTML文件,用JavaScript回调实现同步更新:
from bokeh.models import Select, ColumnDataSource, CustomJS from bokeh.plotting import figure, show from bokeh.layouts import column original_data = {'x': [1,2,3], 'y': [0,1,2], 'names': ['Bob', 'Joe', 'Guy']} updated_data = {'x': [1,2], 'y': [0,1], 'names': ['Joe_updated', 'Guy_updated']} source = ColumnDataSource(data=original_data) p = figure(y_range=(0,2)) p.circle(x='x', y='y', source=source) p.yaxis.major_label_overrides = {0: 'Bob', 1: 'Joe', 2: 'Guy'} select = Select(title="筛选版本", options=["原始", "更新版"]) callback = CustomJS(args=dict(source=source, p=p, original=original_data, updated=updated_data), code=""" const val = cb_obj.value; if (val === "更新版") { source.data = updated; p.yaxis.major_label_overrides = {0: 'Joe_updated', 1: 'Guy_updated'}; p.y_range.start = Math.min(...updated.y); p.y_range.end = Math.max(...updated.y); } else { source.data = original; p.yaxis.major_label_overrides = {0: 'Bob', 1: 'Joe', 2: 'Guy'}; p.y_range.start = 0; p.y_range.end = 2; } source.change.emit(); """) select.js_on_change('value', callback) show(column(select, p))
控制台错误处理
那个TypeError是Bokeh 3.2.x在Chrome严格模式下的内部调用问题,不影响功能。若要消除警告,可将Bokeh升级至3.3.0及以上版本,官方已在后续版本中修复该兼容性问题。
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

