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

Python Bokeh TapTool的CustomJS回调调试求助

我帮你找到了问题所在,并且修正了代码。核心问题是回调绑定的位置不对,另外还有一个小的变量声明问题需要调整。

问题分析

  1. 回调绑定错误:你把CustomJS绑定到了ColumnDataSource的callback属性,这个回调会在数据源发生变化时触发,而不是在点击TapTool时触发。我们需要把回调绑定到TapTool本身,这样点击事件触发时才会执行我们的高亮逻辑。
  2. 未声明变量:代码里的attribute_value没有用var(或let/const)声明,会变成全局变量,可能导致意外的行为。

修正后的完整代码

# Import packages
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, CustomJS, HoverTool, TapTool

# Create the data for the points
x = [0, 1, 2, 3]
y = [0, 1, 0, 1]
ids = ['A','B','A','B']
data = {'x':x, 'y':y, 'id':ids}
source = ColumnDataSource(data)

# Add tools to the plot
tap = TapTool()
hover = HoverTool(tooltips=[("X", "@x"), ("Y", "@y"), ("ID", "@id")])

# Create a plotting figure
p = figure(plot_width=400, plot_height=400, tools=[tap,hover])

# Code for the callback
code = """
// Set column name to select similar glyphs
var column = 'id';
// Get data from ColumnDataSource
var data = source.data;
// Get the index of the clicked item (TapTool gives the single clicked index)
var clickedIndex = cb_obj.selected.indices[0];
// Array to store glyph-indices to highlight
var select_inds = [];

// Get the value of the column to find similar attributes/glyphs
var attribute_value = data[column][clickedIndex];
// Iterate over all entries in the ColumnDataSource
for (var i=0; i<data[column].length; ++i){
    // Check if items have the same attribute
    if(data[column][i] === attribute_value){
        // Add index to selected list
        select_inds.push(i);
    }
}

// Set selected glyphs in ColumnDataSource
source.selected.indices = select_inds;
// Save changes to ColumnDataSource
source.change.emit();
"""

# Create a CustomJS callback with the code and the data
# 注意:这里我们传入cb_obj(即触发回调的TapTool对象)
callback = CustomJS(args={'source': source}, code=code)
# 把回调绑定到TapTool,而不是ColumnDataSource
tap.callback = callback

# Plots circles
p.circle('x', 'y', source=source, size=25, color='blue', alpha=1, hover_color='black', hover_alpha=1,
         # 添加选中样式,让高亮更明显
         selection_color='red', selection_alpha=1)

# Show plot
show(p)

关键修改说明

  • 回调绑定位置:将source.callback = callback改为tap.callback = callback,确保点击事件触发时执行回调逻辑。
  • 获取点击索引:通过cb_obj.selected.indices[0]获取点击的点的索引(cb_obj代表触发回调的TapTool实例),不需要判断长度,因为TapTool默认每次点击只会选中一个点。
  • 变量声明:给attribute_value添加var声明,避免全局变量污染。
  • 添加选中样式:给circle glyph添加selection_color和selection_alpha参数,让选中的点显示红色,高亮效果更直观。
  • 严格相等判断:把==改成===,遵循JS的最佳实践,避免隐式类型转换。

这样修改后,点击任意一个点,所有相同id的点都会被高亮显示(变成红色),完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:52:01