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

如何动态调整Bokeh图表中segment线段的线宽

实现方案

不需要重写整个图表,也无需删除原有segment再重新添加,你已经创建的high_low_segment对象可以直接修改line_width属性,根据你使用场景不同有两种实现路径:

1. Bokeh Server 场景(纯Python实现)

如果你是用bokeh serve运行的交互式服务,直接在Python侧绑定RangesUpdate事件回调即可:

from bokeh.events import RangesUpdate

# 定义回调函数
def adjust_line_width(event):
    # 获取当前x轴的时间范围差(单位:毫秒,适配datetime类型的x轴)
    x_range = p.x_range
    range_span = x_range.end - x_range.start
    # 自定义线宽映射规则,示例规则:放大程度越高、范围越小,线越宽
    if range_span < 7 * 24 * 3600 * 1000: # 显示范围小于7天
        high_low_segment.glyph.line_width = 3
    elif range_span < 30 * 24 * 3600 * 1000: # 显示范围小于30天
        high_low_segment.glyph.line_width = 2
    else:
        high_low_segment.glyph.line_width = 1

# 绑定范围更新事件到图表
p.on_event(RangesUpdate, adjust_line_width)

2. 静态HTML输出场景(需少量JS代码)

如果你是直接输出HTML文件离线使用,不需要启动Bokeh Server,就需要用CustomJS绑定回调:

from bokeh.models import CustomJS

callback = CustomJS(args=dict(segment_glyph=high_low_segment.glyph, x_range=p.x_range), code="""
    // 获取当前x轴范围差
    const range_span = x_range.end - x_range.start
    // 线宽映射规则和Python侧逻辑一致,时间单位为毫秒
    if (range_span < 7 * 24 * 3600 * 1000) {
        segment_glyph.line_width = 3
    } else if (range_span < 30 * 24 * 3600 * 1000) {
        segment_glyph.line_width = 2
    } else {
        segment_glyph.line_width = 1
    }
""")

# 绑定回调到x轴范围变化事件
p.x_range.js_on_change('start', callback)
p.x_range.js_on_change('end', callback)

注意事项

  • 自定义线宽映射规则时,要注意datetime类型的x轴数值单位是unix时间戳毫秒,计算范围差的时候要对应单位
  • 直接修改glyph的属性就会实时渲染,不需要额外调用刷新或者重建图表的方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:45:04