如何用Matplotlib绘制各年份堆叠国家不同的堆叠柱状图?
Hey there! I totally get the frustration of dealing with duplicate legends and clunky loop-based plotting for stacked bars. Let's simplify this using pandas' built-in plotting tools—they'll handle stacking, color consistency, and clean legends in one efficient go.
Step 1: Reshape Your Data for Stacked Plotting
First, we need to convert your long-format DataFrame into a wide format where each year is a row, each country is a column, and values are the total counts. This makes stacked bar plotting trivial:
import pandas as pd import matplotlib.pyplot as plt # Your original dataset data = { 'year': [2010, 2010, 2011, 2011, 2012, 2012, 2013, 2013], 'country': ['USA', 'CHIN', 'USA', 'JAPN', 'KORR', 'USA', 'CHIN', 'USA'], 'total': [10, 12, 8, 12, 7, 10, 9, 13] } df = pd.DataFrame(data) # Reshape to wide format (fill missing country-year pairs with 0) wide_df = df.pivot(index='year', columns='country', values='total').fillna(0)
Step 2: Assign Unique Colors to Countries
Create a color mapping dictionary to lock in consistent colors for each country—this ensures your legend and plot segments match perfectly:
country_colors = { 'USA': '#1f77b4', # Blue 'CHIN': '#ff7f0e', # Orange 'JAPN': '#2ca02c', # Green 'KORR': '#d62728' # Red }
Step 3: Plot the Stacked Bar Chart
Use pandas' plot() method with kind='bar' and stacked=True. Pandas will automatically handle stacking, color assignment, and legend creation—no loops required:
# Generate the stacked bar chart ax = wide_df.plot(kind='bar', stacked=True, color=country_colors, figsize=(10, 6)) # Customize plot labels and styling ax.set_title('Total by Year (Stacked by Country)', fontsize=14) ax.set_xlabel('Year', fontsize=12) ax.set_ylabel('Total', fontsize=12) ax.tick_params(axis='both', labelsize=10) # Adjust legend placement for readability plt.legend(title='Country', bbox_to_anchor=(1.05, 1), loc='upper left') plt.tight_layout() plt.show()
Why This Beats Your Loop Approach
- No redundant legends: Pandas creates one legend entry per country (not per data point), so you’ll only see 4 entries instead of 8.
- Faster plotting: This vectorized approach skips row-by-row loops, making it way more efficient—especially with larger datasets.
- Cleaner code: You avoid manually tracking bar positions and legend handles, reducing room for errors.
This will give you a polished stacked bar chart where each year has a single bar, split into segments for each country present that year, with consistent colors and a tidy legend.
内容的提问来源于stack exchange,提问作者bill

