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

使用TapTool更新Bokeh圆形图选中索引的问题求助

解决Bokeh 0.12.16中TapTool自定义回调无法更新选中点的问题

我来帮你梳理下问题所在,以及对应的解决方案——你遇到的核心问题是在Bokeh 0.12.16这个旧版本中,修改选中状态的方式不符合框架要求,虽然控制台显示数据源的选中索引变了,但图表并没有接收到正确的更新通知,所以没反应。

问题根源拆解

  1. 错误的选中状态修改方式:在Bokeh 0.12.x里,source.selected是一个Selection模型对象,不是普通的JS字典。你直接修改l_selected['1d'].indices或者重新赋值source.selected的操作,没法触发Bokeh内部的变更事件,图表自然不会更新。
  2. 代码小疏漏:你没导入TapTool,而且同时用output_file()和output_notebook()会导致输出冲突,影响运行效果。

修复后的完整代码

下面是调整后可以正常运行的代码,完全贴合你的需求:

from bokeh.layouts import column
from bokeh.models import CustomJS, ColumnDataSource, TapTool  # 补上TapTool的导入
from bokeh.plotting import Figure, output_notebook, show

output_notebook()  # 只保留notebook输出,去掉output_file避免冲突

x = [x*0.005 for x in range(0, 200)]
y = x
source = ColumnDataSource(data=dict(x=x, y=y))

plot = Figure(plot_width=400, plot_height=400)
plot.circle('x', 'y', source=source, line_width=3, line_alpha=0.6)

callback = CustomJS(args=dict(source=source), code="""
    const selectedIndices = source.selected.indices;
    // 只有当点击选中一个点时才执行逻辑
    if (selectedIndices.length === 1) {
        const startIdx = selectedIndices[0];
        const newIndices = [];
        // 生成从点击点开始的50个索引,避免越界
        for (let i = 0; i < 50; i++) {
            const currentIdx = startIdx + i;
            if (currentIdx < source.data.x.length) {
                newIndices.push(currentIdx);
            } else {
                break;
            }
        }
        // 关键:用set方法更新属性,触发Bokeh的变更通知
        source.selected.set('indices', newIndices);
        // 旧版本可能需要手动触发数据源变更事件
        source.change.emit();
    }
""")

# 给TapTool绑定回调
plot.add_tools(TapTool(callback=callback))

layout = column(plot)
show(layout)

核心修改点说明

  • 正确访问选中索引:在0.12.16版本中,直接用source.selected.indices就能获取1D选择的索引数组,不需要绕['1d']这一层。
  • 用set方法更新属性:Bokeh的模型属性必须通过.set('属性名', 新值)的方式修改,这样才能触发内部的更新机制,让图表感知到选中状态的变化。
  • 防止索引越界:加了判断逻辑,避免生成的索引超出数据源的实际长度,防止出现控制台报错。
  • 修复导入和输出问题:补上了TapTool的导入,移除了冲突的output_file()调用,确保在Jupyter Notebook里正常运行。

额外小贴士

如果你之后升级到Bokeh 2.x及以上版本,API会更简洁——直接赋值source.selected.indices = newIndices就可以,不需要set方法,新版本会自动触发变更事件。但针对你现在用的0.12.16,上面的代码是最稳妥的解决方案。

内容的提问来源于stack exchange,提问作者B.Coatanéa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:08:13