绘制含同色系渐变分段的双折线图技术咨询
Got it, let's work through this together! You're looking to create two line charts where each line has gradient color segments across different X-axis regions (using column b to define those segments), and you’ve already got distinct base colors for each line but hit a wall trying to set up the segmented gradients. Here’s a practical, code-driven solution using matplotlib and pandas:
Step 1: Set Up Dependencies and Sample Data
First, let's import the necessary libraries and create sample data that mirrors your use case (you can swap this out with your actual dataset):
import matplotlib.pyplot as plt import pandas as pd import numpy as np from matplotlib.colors import LinearSegmentedColormap # Generate sample data np.random.seed(42) x = np.linspace(0, 20, 100) y1 = np.sin(x) + np.random.normal(0, 0.1, size=len(x)) y2 = np.cos(x) + np.random.normal(0, 0.1, size=len(x)) # Use column 'b' to split X-axis into 4 segments b = pd.cut(x, bins=4, labels=['Segment 1', 'Segment 2', 'Segment 3', 'Segment 4']) df = pd.DataFrame({'x': x, 'y1': y1, 'y2': y2, 'b': b})
Step 2: Create Gradient Color Maps for Each Base Color
We’ll build custom gradient color maps tied to each line’s base color, so each segment gets a lighter/darker shade of the base:
# Define base colors for your two lines base_colors = {'y1': '#1f77b4', 'y2': '#ff7f0e'} # Blue and Orange def create_gradient_cmap(base_hex, num_segments): # Convert hex color to normalized RGB values rgb = tuple(int(base_hex.lstrip('#')[i:i+2], 16)/255 for i in (0, 2, 4)) # Generate light and dark variants of the base color light_shade = tuple(min(c * 1.5, 1) for c in rgb) # Lighter dark_shade = tuple(max(c * 0.5, 0) for c in rgb) # Darker # Create a gradient colormap between the two shades return LinearSegmentedColormap.from_list(f'{base_hex}_grad', [light_shade, dark_shade], N=num_segments) # Get the number of unique segments from column 'b' num_segments = df['b'].nunique()
Step 3: Plot Segmented Lines with Gradient Colors
We’ll group the data by column b, then plot each segment with a corresponding gradient shade. This approach also lets you easily add different line styles per segment if needed:
fig, ax = plt.subplots(figsize=(10, 6)) # Loop through each line to plot for line_name in ['y1', 'y2']: base_color = base_colors[line_name] grad_cmap = create_gradient_cmap(base_color, num_segments) # Group data by column 'b' to get each X-axis segment grouped_data = df.groupby('b') # Plot each segment with a gradient color (and optional line style) for seg_idx, (seg_label, seg_data) in enumerate(grouped_data): # Pick gradient color for this segment segment_color = grad_cmap(seg_idx) # Optional: Add different line styles per segment line_styles = ['-', '--', ':', '-.'] segment_style = line_styles[seg_idx] # Plot the segment ax.plot( seg_data['x'], seg_data[line_name], color=segment_color, linestyle=segment_style, linewidth=2, # Only add label to first segment to avoid duplicate legend entries label=f'{line_name} (base: {base_color})' if seg_idx == 0 else "" ) # Add plot labels and legend ax.set_xlabel('X Axis') ax.set_ylabel('Y Value') ax.set_title('Line Plots with Gradient Color Segments (by Column b)') ax.legend() plt.show()
Key Notes to Fix Your Earlier Line Style Issue
If you struggled with setting different line styles per segment before, it’s likely because you tried applying styles to the entire line instead of plotting each segment individually. By grouping with column b and plotting each segment separately, you can easily assign unique linestyle values (as shown in the code above) to each segment of the line.
内容的提问来源于stack exchange,提问作者joel.wilson

