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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:22:51