Bokeh分段图line_dash能否依赖源数据及参数设置咨询
Great questions about Bokeh's segment plots! Let's break them down clearly:
1. Can the line_dash parameter of a segment plot depend on a data source?
Short answer: Not directly with the segment glyph as you tried—and that's exactly why you're seeing that ValueError.
Bokeh's Segment glyph treats line_dash as a non-vectorized property, meaning it only accepts a single value (like "solid", "dashed", or a custom sequence like [4, 2]) by default. You can't just pass a column name from your ColumnDataSource directly to it, which is why the error complains about getting "dash" instead of an expected dash pattern type.
But don't worry—there are two solid workarounds to get per-segment dash styles:
Workaround 1: Split into multiple segment glyphs with filtered views
Create separate segment calls for each dash style, using CDSView to filter the source data for matching segments:
from bokeh.models import ColumnDataSource, CDSView, IndexFilter from bokeh.plotting import figure, show data = { "dash": ["dashed","dashed","solid"], "x0": [0,1,2], "x1": [5,6,8], "y0": [1,1,1], "y1": [2,1,2] } source = ColumnDataSource(data) plot = figure() # Plot dashed segments dashed_indices = [i for i, d in enumerate(data["dash"]) if d == "dashed"] view_dashed = CDSView(source=source, filters=[IndexFilter(dashed_indices)]) plot.segment(x0="x0", y0="y0", x1="x1", y1="y1", line_dash="dashed", source=source, view=view_dashed) # Plot solid segments solid_indices = [i for i, d in enumerate(data["dash"]) if d == "solid"] view_solid = CDSView(source=source, filters=[IndexFilter(solid_indices)]) plot.segment(x0="x0", y0="y0", x1="x1", y1="y1", line_dash="solid", source=source, view=view_solid) show(plot)
Workaround 2: Use multi_line instead
The multi_line glyph supports vectorized line_dash (meaning it can pull values from a data source column). You just need to restructure your data so each segment is represented as a tiny list of two points:
from bokeh.models import ColumnDataSource from bokeh.plotting import figure, show data = { "dash": ["dashed","dashed","solid"], "xs": [[0,5], [1,6], [2,8]], # Each entry is [x0, x1] for a segment "ys": [[1,2], [1,1], [1,2]] # Each entry is [y0, y1] for a segment } source = ColumnDataSource(data) plot = figure() plot.multi_line(xs="xs", ys="ys", line_dash="dash", source=source) show(plot)
2. Is line_dash only allowed to be a single value? How to tell which parameters support "local" vs "global" settings?
First, line_dash isn't always restricted to a single value—it depends on the glyph you're using. For example, multi_line and scatter (with line elements) let you set line_dash per-glyph element by binding it to a data source column. But for glyphs like segment or rect, line_dash is currently non-vectorized, so it only accepts a global single value.
To figure out which properties support local (per-element) vs global settings:
- Check the Bokeh docs: Each glyph's property documentation will note if it's vectorized (or accepts "field" references). For example,
Segment'sx0is aNumberSpec(supports fields), whileline_dashis aDashPattern(only accepts scalar values). - Quick test: If setting a property to a column name throws an error like the one you saw, it's non-vectorized (global-only). If it runs without errors and applies the value per element, it's vectorized (local-friendly).
- General rule of thumb: Position-related properties (like
x0,y0,x,y) are almost always vectorized. Style properties (likeline_dash,line_cap,fill_alpha) vary by glyph—some support per-element customization, others don't.
内容的提问来源于stack exchange,提问作者Leevi L

