Bokeh中Whisker误差棒头部颜色修改及替代方案问询
Great question! The issue you're hitting is that the line_color property only affects the vertical stem of the Whisker, not the horizontal heads. Bokeh actually has separate attributes for styling the head elements, which is why your heads stayed black even after setting the stem color.
Quick Fix: Match Head and Stem Color
To make the whisker heads match the stem color, you just need to add the whisker_head_line_color property to your Whisker definition. Here's how to update your original code:
from bokeh.models import ColumnDataSource, Whisker from bokeh.plotting import figure, show from bokeh.sampledata.autompg import autompg as df colors = ["red", "olive", "darkred", "goldenrod", "skyblue", "orange", "salmon"] p = figure(plot_width=600, plot_height=300, title="Years vs mpg with Quartile Ranges") base, lower, upper = [], [], [] for i, year in enumerate(list(df.yr.unique())): year_mpgs = df[df['yr'] == year]['mpg'] mpgs_mean = year_mpgs.mean() mpgs_std = year_mpgs.std() lower.append(mpgs_mean - mpgs_std) upper.append(mpgs_mean + mpgs_std) base.append(year) source_error = ColumnDataSource(data=dict(base=base, lower=lower, upper=upper)) # Add whisker_head_line_color to sync head color with stem p.add_layout( Whisker(source=source_error, base="base", upper="upper", lower="lower", line_color='red', whisker_head_line_color='red') ) for i, year in enumerate(list(df.yr.unique())): y = df[df['yr'] == year]['mpg'] color = colors[i % len(colors)] p.circle(x=year, y=y, color=color) show(p)
Better: Match Whisker Color to Each Year's Data Points
If you want each year's error bars to match the color of its corresponding data points (instead of a single red), you can create individual Whisker objects for each year. This way, you can tie the error bar color directly to the point color:
from bokeh.models import ColumnDataSource, Whisker from bokeh.plotting import figure, show from bokeh.sampledata.autompg import autompg as df colors = ["red", "olive", "darkred", "goldenrod", "skyblue", "orange", "salmon"] p = figure(plot_width=600, plot_height=300, title="Years vs mpg with Quartile Ranges") for i, year in enumerate(list(df.yr.unique())): year_mpgs = df[df['yr'] == year]['mpg'] mpgs_mean = year_mpgs.mean() mpgs_std = year_mpgs.std() lower = mpgs_mean - mpgs_std upper = mpgs_mean + mpgs_std color = colors[i % len(colors)] # Create a dedicated data source for this year's whisker source = ColumnDataSource(data=dict(base=[year], lower=[lower], upper=[upper])) # Assign matching color to both stem and head p.add_layout( Whisker(source=source, base="base", upper="upper", lower="lower", line_color=color, whisker_head_line_color=color) ) # Plot data points with the same color p.circle(x=year, y=year_mpgs, color=color) show(p)
Key Styling Properties for Whiskers
For future reference, Bokeh's Whisker model has several properties to customize the heads:
whisker_head_line_color: Controls the color of the horizontal head lineswhisker_head_line_width: Adjusts the thickness of the head lineswhisker_head_line_alpha: Sets the transparency of the heads
These let you fully style both parts of the error bar to match your plot's design.
内容的提问来源于stack exchange,提问作者Admed

