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

Bokeh Server:如何在回调函数中批量选中同组Patch元素

解决Bokeh点击Patch高亮同组所有元素的问题

我来帮你搞定这个Bokeh的选择高亮问题!你现在的代码里,直接赋值source.selected.indices没法正确触发Bokeh的视图更新,所以同组Patch没被高亮。下面是修复后的完整代码,以及关键的修改说明:

问题根源

你遇到的核心问题是:直接修改source.selected.indices这个属性时,Bokeh的属性变更检测机制没被触发——因为这是对对象属性的直接赋值,不是通过Bokeh推荐的方法更新的,所以图表不会同步更新选中状态。另外,你用df['id']来获取组索引的方式虽然当前数据没问题,但不够健壮,最好直接用数据源的行索引来定位元素。

修复后的完整代码

import os
from bokeh.models import ColumnDataSource, Patches
from bokeh.plotting import figure
from bokeh.layouts import row
from bokeh.io import output_file, curdoc
import pandas as pd

x = [[1,2,4], [3,5,6], [7,9,7], [5,7,6]]
y = [[4,2,1], [6,5,8], [3,9,6], [2,2,1]]
group = ['A', 'A', 'B', 'B']
id = [0,1,2,3]

df = pd.DataFrame(data=dict(x=x, y=y, group=group, id=id))
source = ColumnDataSource(df)

p = figure(tools="tap")
renderer = p.patches('x', 'y', source=source)

# 设置选中后的样式
selected_patches = Patches(fill_color="#a6cee3")
renderer.selection_glyph = selected_patches

# 点击事件处理函数
def my_tap_handler(attr, old, new):
    # 先判断是否有点击到元素,避免空索引报错
    if not new['1d']['indices']:
        return
    # 获取点击元素的组名
    clicked_idx = new['1d']['indices'][0]
    group_name = source.data['group'][clicked_idx]
    # 获取同组所有元素的行索引(更可靠的方式)
    group_indices = df.index[df['group'] == group_name].tolist()
    # 使用update方法更新选中状态,触发Bokeh的视图更新
    source.selected.update(indices=group_indices)
    print("当前选中索引:", source.selected.indices)

# 绑定选中变更事件
renderer.data_source.on_change("selected", my_tap_handler)

# 添加到文档
curdoc().add_root(row(p, width=800))

关键修改说明

  • 用source.selected.update()替代直接赋值:这个方法会主动触发Bokeh的属性变更通知,让图表立刻更新选中的高亮状态,这是解决问题的核心。
  • 改用行索引获取组元素:通过df.index[df['group'] == group_name]直接拿到数据源的行索引,不再依赖id列和索引的一致性,代码更健壮,后续数据有变化也不容易出错。
  • 增加空值判断:先检查new['1d']['indices']是否为空,防止用户点击图表空白区域时出现索引越界的错误。

这样修改后,你点击任意一个Patch,同组的所有Patch都会立刻被高亮选中,完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:53:35