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

如何在Python中同图对齐绘制年度叶绿素a与月度MEI.V2数据?

解决Matplotlib绘制不同频率时间序列数据的对齐问题

问题背景

需要在同一张图中展示1998-2021年的年度叶绿素a浓度和月度MEI.V2指数:

  • 左y轴对应叶绿素a浓度
  • 右y轴对应MEI.V2指数
  • 要求月度MEI.V2数据与x轴年份正确对齐

原代码生成的图表存在时间轴对齐异常,x轴年份与数据不匹配。

测试数据代码

import numpy as np
import pandas as pd

# Generate yearly chlorophyll-a concentration data
np.random.seed(0)
dates = pd.date_range(start='1998-01-01', end='2021-12-31', freq='Y')
chlorophyll_data = np.random.uniform(low=0, high=5, size=len(dates))
chlorophyll_df = pd.DataFrame({'Date': dates, 'Chlorophyll-a': chlorophyll_data})

# Generate monthly MEI.V2 data
monthly_dates = pd.date_range(start='1998-01-01', end='2021-12-31', freq='M')
mei_data = np.random.uniform(low=-2, high=2, size=len(monthly_dates))
mei_df = pd.DataFrame({'Date': monthly_dates, 'MEI.V2': mei_data})

原尝试代码

import matplotlib.pyplot as plt

fig, ax1 = plt.subplots(figsize=(12, 6))

# Primary y-axis (left)
ax1.plot(chlorophyll_df.index, chlorophyll_df['Chlorophyll-a'], marker='P', linestyle='-', linewidth=2)
ax1.set_ylabel('Chlorophyll-a concentration [mg $m^{-3}$]')
ax1.legend(ncol=4, loc='upper center')

# Explicitly set the x-axis range
plt.xlim(1998, 2021)

# Secondary y-axis (right)
ax2 = ax1.twinx()
ax2.plot(mei_df.index, mei_df['MEI.V2'], color='red', linestyle='-')
ax2.set_ylabel('MEI.V2', color='red')
ax2.tick_params(axis='y')
ax2.legend(loc='upper right')

# Plot formatting
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()

问题根源

  1. 原代码使用DataFrame的默认整数索引绘图,而非实际的时间列Date,导致Matplotlib无法识别时间序列,无法正确对齐数据
  2. plt.xlim(1998,2021)是针对数值轴的设置,不适用于时间轴,无法正确限制时间范围

修正后的代码

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# ---------------------- 数据预处理 ----------------------
np.random.seed(0)
# 年度叶绿素a数据:将Date设为时间索引
dates = pd.date_range(start='1998-01-01', end='2021-12-31', freq='Y')
chlorophyll_data = np.random.uniform(low=0, high=5, size=len(dates))
chlorophyll_df = pd.DataFrame({'Chlorophyll-a': chlorophyll_data}, index=dates)

# 月度MEI.V2数据:将Date设为时间索引
monthly_dates = pd.date_range(start='1998-01-01', end='2021-12-31', freq='M')
mei_data = np.random.uniform(low=-2, high=2, size=len(monthly_dates))
mei_df = pd.DataFrame({'MEI.V2': mei_data}, index=monthly_dates)

# ---------------------- 绘图实现 ----------------------
fig, ax1 = plt.subplots(figsize=(12, 6))

# 左轴:年度叶绿素a
ax1.plot(chlorophyll_df.index, chlorophyll_df['Chlorophyll-a'], 
         marker='P', linestyle='-', linewidth=2, label='Chlorophyll-a')
ax1.set_ylabel('Chlorophyll-a concentration [mg $m^{-3}$]')
ax1.set_xlabel('Year')
ax1.legend(loc='upper center')
ax1.tick_params(axis='both', labelsize=10)

# 右轴:月度MEI.V2
ax2 = ax1.twinx()
ax2.plot(mei_df.index, mei_df['MEI.V2'], 
         color='red', linestyle='-', label='MEI.V2')
ax2.set_ylabel('MEI.V2', color='red')
ax2.tick_params(axis='y', labelcolor='red', labelsize=10)
ax2.legend(loc='upper right')

# 优化时间轴显示
fig.autofmt_xdate(rotation=45)  # 自动旋转日期标签,避免重叠
plt.tight_layout()
plt.show()

关键修正点

  • 将Date列设置为DataFrame的时间索引,让Matplotlib自动识别时间序列,实现数据与年份的正确对齐
  • 移除无效的plt.xlim(1998,2021),时间范围由时间索引自动适配
  • 优化图例位置和标签样式,提升图表可读性
  • 使用fig.autofmt_xdate()自动处理x轴日期标签的旋转,解决标签重叠问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 12:05:36