如何通过编程更新Bokeh数据源选中索引并触发视图重绘?
解决Bokeh编程方式设置选中点不更新的问题
我明白你遇到的困扰了——直接用source.selected.update(indices=[4])确实只会修改属性值,但不会触发Bokeh的变更事件,导致图表没重绘、回调函数也没执行。这是因为Bokeh的模型属性(比如Selection的indices)是通过专门的属性系统来追踪变化的,普通的字典更新方法绕开了这个系统,自然不会触发后续的更新逻辑。
正确的解决方法
你只需要直接给source.selected.indices赋值,而不是用update方法:
def update_selection_programmatically(): source.selected.indices = [4] # 直接赋值触发属性变更事件
为什么这样可行?
Bokeh的ColumnDataSource和Selection都是Bokeh模型对象,它们的属性变更会被内部的属性系统实时监听。当你直接对indices属性赋值时,系统会自动检测到变化,同步触发两个关键行为:
- 重绘图表,将目标点标记为选中状态
- 调用你通过
source.on_change('selected', update_selection)注册的回调函数
修改后的完整代码
from bokeh.io import curdoc from bokeh.models import ColumnDataSource from bokeh.plotting import figure from bokeh.layouts import column from bokeh.models.tools import LassoSelectTool, TapTool from bokeh.models.widgets.buttons import Button source = ColumnDataSource(dict( x=[1, 2, 3, 4, 5, 6], y=[1, 2, 3, 4, 5, 6], )) p = figure( plot_height=300, tools='', ) p.circle( x='x', y='y', size=20, source=source) lasso_select = LassoSelectTool( select_every_mousemove=False, ) tap = TapTool() tools = (lasso_select, tap) p.add_tools(*tools) def update_selection_programmatically(): source.selected.indices = [4] # 改为直接赋值触发更新 bt = Button( label="Update Selection", button_type="success", width=50 ) bt.on_click(update_selection_programmatically) def update_selection(attr, old, new): print('>> NEW SELECTION: {}'.format(new.indices)) source.on_change('selected', update_selection) curdoc().add_root(column([p, bt]))
现在点击按钮后,索引为4的点会被正确标记为选中,同时控制台也会打印出选中的索引信息,完全符合你的预期~
内容的提问来源于stack exchange,提问作者ChesuCR
相关产品推荐
相关产品推荐

