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

如何使用CDS列设置Multiline字形的line_dash属性?

解决Bokeh multi_line绑定line_dash到CDS列的问题

嘿,我来帮你解决这个Bokeh里的小坑——确实multi_line的line_dash没法直接绑定CDS列,但有几个靠谱的办法能实现你的需求,还能兼顾性能:

一、先说说问题根源

你观察得很准:Bokeh的multi_line目前原生不支持把line_dash映射到CDS列,而color、line_width这类属性其实底层支持向量化映射,只是文档没跟上(你发现的line_width文档遗漏的情况,确实是个小疏漏,之后可以去Bokeh的GitHub提个issue补全文档)。

二、两种可行解决方案

1. 用CustomJS动态设置线型(灵活适配任意分组)

如果你的线型规则比较复杂,或者需要动态变更,用CustomJS回调是最灵活的方式。它能在前端根据CDS里的dash列值,逐个设置每条线的线型,性能损耗几乎可以忽略:

from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, CustomJS

source = ColumnDataSource(data=dict(
    x=[3, 3],
    y=[4, 4],
    xs1=[[1, 2, 3], [2, 3, 4]],
    ys1=[[6, 7, 2], [4, 5, 7]],
    color=['red', 'green'],
    width=[5, 1],
    dash=['solid', 'dashed']
))

p = figure(
    plot_width=400,
    plot_height=400,
    tools='lasso_select,pan,wheel_zoom'
)

# 先渲染多线,暂不设置line_dash
renderer = p.multi_line(
    xs='xs1',
    ys='ys1',
    source=source,
    color='color',
    line_join='round',
    line_width='width'
)

# 写个JS回调,根据CDS的dash列设置每条线的线型
callback = CustomJS(args=dict(renderer=renderer, source=source), code="""
    const dashValues = source.data.dash;
    const glyphs = renderer.glyphs;
    // 遍历每条线,设置对应的线型
    for (let i = 0; i < dashValues.length; i++) {
        glyphs[i].line_dash = dashValues[i];
    }
""")

# 绑定回调到数据源的data变化事件
source.js_on_change('data', callback)
# 初始加载时手动触发一次回调,确保线型生效
callback.trigger('data', source.data, source.data)

show(p)

2. 拆分数据源(性能最优的极简方案)

如果你的需求只是「主线solid,其余dashed」,那拆分数据源是最省事儿的——把主线单独用一个multi_line渲染,剩下的虚线用另一个multi_line批量处理,这样既不用写复杂的回调,性能也和原方案几乎一致:

from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource

# 拆分数据:单独拎出主线,剩下的归为其他线
main_line_source = ColumnDataSource(data=dict(
    xs=[[1, 2, 3]],
    ys=[[6, 7, 2]],
    color=['red'],
    width=[5]
))

dashed_lines_source = ColumnDataSource(data=dict(
    xs=[[2, 3, 4]],
    ys=[[4, 5, 7]],
    color=['green'],
    width=[1]
))

p = figure(
    plot_width=400,
    plot_height=400,
    tools='lasso_select,pan,wheel_zoom'
)

# 主线设置solid线型
p.multi_line(
    xs='xs',
    ys='ys',
    source=main_line_source,
    color='color',
    line_join='round',
    line_width='width',
    line_dash='solid'
)

# 其余线统一设置dashed线型
p.multi_line(
    xs='xs',
    ys='ys',
    source=dashed_lines_source,
    color='color',
    line_join='round',
    line_width='width',
    line_dash='dashed'
)

show(p)

最后补充下文档的问题

你提到的line_width能绑定CDS列但文档没说明,这确实是Bokeh文档的一个小遗漏。如果有精力的话,去Bokeh的GitHub仓库提交一个issue或者PR,能帮到更多开发者哦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:14:16