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

Holoviews:配置Curve与Spread叠加图的图例及颜色

Solution: Pairing Curves and Spreads with Matching Colors & Legends in Holoviews

I’ve run into this exact issue before—Holoviews can be finicky when combining different element types while preserving styling and legends. Here’s how to fix it, with two straightforward approaches:


Approach 1: Manual Pairing (Full Control)

This method lets you explicitly define colors for each Curve-Spread pair, ensuring perfect matching and a clean legend.

Step 1: Prepare Your Data

First, compute the lower/upper bounds for your error spread (since hv.Spread expects these instead of just an error value):

import pandas as pd
import numpy as np
import holoviews as hv
hv.extension('bokeh')

# Sample data (replace with your own)
np.random.seed(42)
groups = ['Group 1', 'Group 2', 'Group 3', 'Group 4']
x = np.linspace(0, 10, 20)
df = pd.DataFrame({
    'x': np.tile(x, len(groups)),
    'index_col': np.repeat(groups, len(x)),
    'y': np.concatenate([x + np.random.normal(0, 0.5, len(x)) + i*2 for i in range(len(groups))]),
    'error': np.concatenate([np.full(len(x), 0.8 + i*0.2) for i in range(len(groups))])
})

# Calculate error bounds
df['lower'] = df['y'] - df['error']
df['upper'] = df['y'] + df['error']

Step 2: Create Paired Curve + Spread Elements

Use Holoviews’ default color cycle to assign matching colors to each pair:

# Get Holoviews' default color palette
colors = hv.Cycle('default').values

# Build list of paired elements
composite_elements = []
for i, group in enumerate(groups):
    # Filter data for the current group
    group_data = df[df['index_col'] == group]
    
    # Create Curve with label (shows in legend)
    curve = hv.Curve(group_data, 'x', 'y', label=group).opts(
        color=colors[i], line_width=2
    )
    
    # Create Spread with matching color (transparent fill, no border)
    spread = hv.Spread(group_data, 'x', ['lower', 'upper']).opts(
        fill_color=colors[i], fill_alpha=0.3, line_color=None
    )
    
    # Combine Curve and Spread into a single element
    composite_elements.append(curve * spread)

# Overlay all paired elements
final_plot = hv.Overlay(composite_elements).opts(
    hv.opts.Curve(legend_position='right'),
    hv.opts.Spread(show_legend=False)  # Hide spread from legend (Curve already represents it)
)

final_plot

Approach 2: Holomap Combination (Leveraging to() Method)

If you prefer using Holoviews’ to() method to generate Holomaps, you can combine them while preserving color matching:

# Generate Holomaps for Curves and Spreads
curve_hmap = df.to(hv.Curve, 'x', 'y', groupby='index_col')
spread_hmap = df.to(hv.Spread, 'x', ['lower', 'upper'], groupby='index_col')

# Create a Holomap of paired Curve+Spread elements
combined_hmap = hv.HoloMap(
    {k: curve_hmap[k] * spread_hmap[k] for k in curve_hmap.keys()},
    kdims='index_col'
)

# Overlay the paired elements and style them
final_plot = combined_hmap.overlay().opts(
    # Style Curves (legend will use these labels/colors)
    hv.opts.Curve(legend_position='right', line_width=2),
    # Style Spreads to match their Curve's color
    hv.opts.Spread(fill_alpha=0.3, line_color=None, color=hv.Cycle('default'))
)

final_plot

Why Your Original Approaches Failed

  • Spread Overlays: Spreads don’t generate legend entries by default (they’re area elements, not line markers).
  • Mismatched Colors: When overlaying separate Curve and Spread Holomaps, Holoviews uses independent color cycles for each overlay, leading to mismatched pairs.
  • Legend Loss: Combining overlays directly can break legend handling unless elements are explicitly paired and styled.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:47:24