如何在TextInput值变化时更新Bokeh Circle的kwargs参数?
实现TextInput触发Bokeh Circle高亮的可行方案
核心思路
Bokeh中直接修改Circle glyph的静态属性(比如color)无法动态生效,必须通过ColumnDataSource绑定动态字段,通过更新数据源来实现样式变化。我们可以给数据源添加一个用于控制样式的字段(比如color),在TextInput值变化时,根据text列的匹配情况更新这个字段,Circle会自动同步样式。
方案一:客户端静态页面(CustomJS回调)
适合不需要Python后端的静态可视化场景,用JavaScript处理逻辑:
from bokeh.plotting import figure, show from bokeh.models import ColumnDataSource, TextInput, CustomJS from bokeh.layouts import column # 模拟数据源 data = { 'x': [1, 2, 3, 4, 5], 'y': [2, 4, 1, 3, 5], 'text': ['apple', 'banana', 'apricot', 'blueberry', 'cherry'] } # 给数据源添加样式控制字段,默认颜色为灰色 data['color'] = ['#888888'] * len(data['x']) source = ColumnDataSource(data=data) # 创建绘图和Circle glyph,绑定数据源的color字段 p = figure(width=500, height=300) circle = p.circle(x='x', y='y', color='color', size=10, source=source) # 创建TextInput组件 text_input = TextInput(value='', title='输入前缀:', width=200) # 编写CustomJS回调 callback = CustomJS(args=dict(source=source, input=text_input), code=""" const data = source.data; const prefix = input.value.trim(); const text = data['text']; const color = data['color']; // 遍历所有数据点,根据前缀匹配更新颜色 for (let i = 0; i < text.length; i++) { if (prefix === '' || text[i].startsWith(prefix)) { color[i] = '#ff0000'; // 匹配的点设为红色高亮 } else { color[i] = '#888888'; // 不匹配的点恢复默认灰色 } } // 通知数据源更新,触发视图刷新 source.change.emit(); """) # 绑定TextInput的value变化事件到回调 text_input.js_on_change('value', callback) # 布局并展示 layout = column(text_input, p) show(layout)
方案二:服务器端(Bokeh Server回调)
如果需要用Python处理复杂逻辑,或者依赖后端数据,用Bokeh Server的Python回调:
from bokeh.plotting import figure, curdoc from bokeh.models import ColumnDataSource, TextInput from bokeh.layouts import column # 模拟数据源 data = { 'x': [1, 2, 3, 4, 5], 'y': [2, 4, 1, 3, 5], 'text': ['apple', 'banana', 'apricot', 'blueberry', 'cherry'] } data['color'] = ['#888888'] * len(data['x']) source = ColumnDataSource(data=data) # 创建绘图 p = figure(width=500, height=300) p.circle(x='x', y='y', color='color', size=10, source=source) # 创建TextInput text_input = TextInput(value='', title='输入前缀:', width=200) # Python回调函数 def update_highlight(attr, old, new): prefix = new.strip() # 更新color字段 new_colors = [] for txt in source.data['text']: if prefix == '' or txt.startswith(prefix): new_colors.append('#ff0000') else: new_colors.append('#888888') # 给数据源赋值,自动触发刷新 source.data['color'] = new_colors # 绑定回调 text_input.on_change('value', update_highlight) # 添加到文档 curdoc().add_root(column(text_input, p))
运行方式:保存为app.py,执行bokeh serve --show app.py
关键说明
- 必须通过ColumnDataSource的字段绑定glyph属性,而不是直接设置静态值(比如
color='#888888'),只有绑定字段才能动态更新。 - 客户端回调用
source.change.emit()通知视图更新,服务器端直接修改source.data即可自动触发刷新。 - 可以扩展控制其他属性,比如
size、alpha等,只需要在数据源中添加对应字段并绑定到Circle的kwargs即可。
内容的提问来源于stack exchange,提问作者Jules
相关产品推荐
相关产品推荐

