Bokeh问题:vbar无法随滑块更新但circle可正常更新
搞定Bokeh vbar滑块不更新的问题!
哥们,我太懂你踩的这个坑了——Bokeh里circle和vbar的更新逻辑确实不一样,尤其是在0.12.13这个老版本里,稍不注意就会掉进去。我帮你拆解下问题根源,再给你个能跑的修正示例:
核心问题:vbar的属性绑定逻辑和circle不同
Circle这类点图只要绑定了ColumnDataSource的字段,数据源更新就会自动同步;但vbar的top、x这些属性如果是直接传静态数值(而不是数据源字段名),那滑块拖动时完全不会感知到数据源的变化,自然就不动了。
常见错误场景&修正方法
先模拟下你可能写错的代码(典型错误写法):
from bokeh.io import curdoc from bokeh.models import ColumnDataSource, Slider from bokeh.plotting import figure from bokeh.layouts import column # 初始化数据源 source = ColumnDataSource(data={'x': [1,2,3], 'y': [10,20,30]}) p = figure() # ❌ 错误:直接传初始数值,没绑定数据源字段 p.vbar(x=[1,2,3], top=source.data['y'], width=0.5) # 滑块回调 def update(attr, old, new): new_y = [i*new for i in [1,2,3]] source.data = {'x': [1,2,3], 'y': new_y} slider = Slider(start=1, end=10, value=1, title="Multiplier") slider.on_change('value', update) curdoc().add_root(column(slider, p))
这里vbar的top是直接取了数据源的初始值,不是绑定字段,所以后续数据源更新时,vbar根本不知道要跟着变。
修正后的代码
把vbar的x和top都绑定到数据源的字段,并且明确指定source参数:
from bokeh.io import curdoc from bokeh.models import ColumnDataSource, Slider from bokeh.plotting import figure from bokeh.layouts import column # 初始化数据源,包含vbar需要的所有字段 source = ColumnDataSource(data={'x_vals': [1,2,3], 'top_vals': [10,20,30]}) p = figure(x_range=(0.5, 3.5)) # 固定x范围,避免条形位置乱跑 # ✅ 正确:绑定数据源字段,指定source p.vbar(x='x_vals', top='top_vals', width=0.5, source=source) # 滑块回调:更新数据源里的top_vals字段 def update(attr, old, new): new_top = [i*new for i in [1,2,3]] # 用patch部分更新,比替换整个data更高效(老版本也支持) source.patch({'top_vals': [(slice(None), new_top)]}) # 也可以用 source.data = {'x_vals': [1,2,3], 'top_vals': new_top} slider = Slider(start=1, end=10, value=1, title="Multiplier") slider.on_change('value', update) curdoc().add_root(column(slider, p))
针对0.12.13版本的额外提醒
- 必须用
ColumnDataSource作为数据源,别直接传列表/字典给vbar; - 如果x轴是分类值,提前设置好
x_range,否则更新后条形可能消失; - 回调里尽量用
source.patch()做部分更新,比替换整个source.data更稳定。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

