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

如何在堆叠柱状图中指定X轴标签显示间隔(每3个月)

Solution for Stacked Monthly Catch Bar Chart by Size Code

Hey Helen, let's tackle this step by step—your goal is totally achievable with pandas and matplotlib. Here's a detailed breakdown of how to get that stacked bar chart with readable X-axis labels:

1. Data Preprocessing First

First, we need to clean up the date data and aggregate the catch by month and size code. Let's start with that:

import pandas as pd
import matplotlib.pyplot as plt

# Convert Date column to datetime (critical for time-based grouping)
df['Date'] = pd.to_datetime(df['Date'])

# Create a 'Month' column that represents the first day of each month (keeps datetime format)
df['Month'] = df['Date'].dt.to_period('M').dt.to_timestamp()

# Aggregate total weight by Month and Size.Code, then pivot to wide format for stacking
aggregated_df = df.groupby(['Month', 'Size.Code'])['Weight'].sum().unstack(fill_value=0)

Quick Notes:

  • Using to_period('M').dt.to_timestamp() ensures our monthly data is ordered correctly (no messy string sorting).
  • unstack() turns Size.Code values into columns—this is what lets matplotlib create stacked bars automatically.

2. Plot the Stacked Bar Chart

Now let's build the chart with the X-axis label spacing you want:

fig, ax = plt.subplots(figsize=(14, 7))

# Plot stacked bars directly from the aggregated dataframe
aggregated_df.plot(kind='bar', stacked=True, ax=ax, colormap='viridis')

# Customize X-axis labels to show every 3 months
# Get all tick positions and their corresponding labels
all_ticks = ax.get_xticks()
all_labels = [date.strftime('%Y-%m') for date in aggregated_df.index]

# Only keep labels every 3 months, leave others blank
visible_labels = [label if i % 3 == 0 else '' for i, label in enumerate(all_labels)]
ax.set_xticklabels(visible_labels, rotation=45, ha='right')

# Add titles and labels for clarity
ax.set_title('10-Year Monthly Catch by Size Code', fontsize=16)
ax.set_xlabel('Month', fontsize=12)
ax.set_ylabel('Total Catch Weight', fontsize=12)

# Move legend outside the plot to avoid overlapping bars
ax.legend(title='Size Code', bbox_to_anchor=(1.02, 1), loc='upper left')

plt.tight_layout()
plt.show()

3. If You Want Separate Charts for Each Vessel

If you need individual stacked charts for each Vessel.Pln, wrap the plotting code in a loop:

# Get all unique vessel identifiers
unique_vessels = df['Vessel.Pln'].unique()

for vessel in unique_vessels:
    # Filter data for the current vessel
    vessel_data = df[df['Vessel.Pln'] == vessel]
    # Aggregate catch for this vessel
    vessel_agg = vessel_data.groupby(['Month', 'Size.Code'])['Weight'].sum().unstack(fill_value=0)
    
    # Create plot
    fig, ax = plt.subplots(figsize=(12, 6))
    vessel_agg.plot(kind='bar', stacked=True, ax=ax, colormap='viridis')
    
    # Apply the same 3-month label spacing
    all_labels = [date.strftime('%Y-%m') for date in vessel_agg.index]
    visible_labels = [label if i % 3 == 0 else '' for i, label in enumerate(all_labels)]
    ax.set_xticklabels(visible_labels, rotation=45, ha='right')
    
    # Customize titles for each vessel
    ax.set_title(f'Monthly Catch by Size Code - Vessel {vessel}', fontsize=14)
    ax.set_xlabel('Month', fontsize=12)
    ax.set_ylabel('Total Catch Weight', fontsize=12)
    ax.legend(title='Size Code', bbox_to_anchor=(1.02, 1), loc='upper left')
    
    plt.tight_layout()
    plt.show()

Key Tips to Avoid Issues:

  • Handle Missing Data: If you have missing dates or weights, add df = df.dropna(subset=['Date', 'Weight']) and df['Weight'] = pd.to_numeric(df['Weight'], errors='coerce') to clean the data first.
  • Adjust Figure Size: Tweak the figsize parameter if your labels still feel crowded—wider figures work better for long time periods.
  • Color Customization: Replace colormap='viridis' with any matplotlib colormap you prefer (e.g., 'tab20' for distinct colors).

内容的提问来源于stack exchange,提问作者helen.h

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:34:15