河南省 2025 年每日降水对比 2020-2025 年均值(Python 绘图教程)

本文展示如何使用 Python 对河南省 2020-2025 年的每日降水数据进行可视化,绘制 2025 年实际降水与 6 年平均降水对比图,并用渐变色带标注高于或低于均值区域,同时标注播种期和收获期。


1. 导入必要库

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import rcParams
from matplotlib.patches import Patch
from matplotlib.dates import MonthLocator, DayLocator, DateFormatter
  • pandas:数据读取与处理
  • matplotlib:绘图
  • numpy:数值计算
  • Patch:自定义图例色块
  • MonthLocator / DayLocator / DateFormatter:控制日期轴显示

2. 读取数据

df = pd.read_excel("Henan_ERA5_2020_2025_Daily.xlsx")
df.columns = ["Year", "Month", "Day", "Tmean_C", "Tmax_C", "Tmin_C",
              "Soil0_7cm_m3m3", "Precip_mm", "Evap_mm"]

df['Date'] = pd.to_datetime(df[['Year','Month','Day']], errors='coerce')
  • 将年/月/日列合并为 Date 列,方便绘图和筛选
  • errors='coerce' 可以自动处理无效日期(如闰年 2 月 29 日)

3. 计算 2020-2025 年每日平均降水

df_ref = df[df["Year"].between(2020, 2025)]
daily_mean = df_ref.groupby(["Month","Day"])["Precip_mm"].mean().reset_index()
daily_mean = daily_mean[~((daily_mean['Month']==2) & (daily_mean['Day']==29))]
daily_mean['Date'] = pd.to_datetime(dict(year=2025,
                                         month=daily_mean['Month'],
                                         day=daily_mean['Day']))
  • 分组计算每日平均降水
  • 删除 2 月 29 日,保证与非闰年对齐
  • 对齐到 2025 年日期,用于绘图

4. 提取 2025 年每日降水数据

df_2025 = df[df["Year"] == 2025].sort_values("Date")
df_2025 = df_2025[~((df_2025['Month']==2) & (df_2025['Day']==29))]
  • 只保留 2025 年数据
  • 删除闰年 2 月 29 日

5. 设置绘图样式

rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'STSong']
rcParams['axes.unicode_minus'] = False

fig, ax = plt.subplots(figsize=(12, 4), dpi=150)
  • 设置中文字体,确保图例和标签正确显示
  • 创建画布,尺寸为 12x4 英寸,分辨率 150 dpi

6. 渐变色带函数

def gradient_fill(x, y1, y2, color_high, color_low):
    y1, y2 = np.array(y1), np.array(y2)
    for i in range(len(x)-1):
        if y1[i] >= y2[i]:
            alpha = 0.3 + 0.2 * (y1[i:i+2].mean() - y2[i:i+2].mean()) / max(y1.max()-y2.min(), 1e-6)
            ax.fill_between(x[i:i+2], y1[i:i+2], y2[i:i+2],
                             color=color_high, alpha=alpha, interpolate=True)
        else:
            alpha = 0.3 + 0.2 * (y2[i:i+2].mean() - y1[i:i+2].mean()) / max(y2.max()-y1.min(), 1e-6)
            ax.fill_between(x[i:i+2], y1[i:i+2], y2[i:i+2],
                             color=color_low, alpha=alpha, interpolate=True)
  • color_high:高于均值区域填充色
  • color_low:低于均值区域填充色
  • 根据差值动态调整透明度,视觉效果更自然

7. 绘制渐变色带与折线

# 渐变色带
gradient_fill(df_2025['Date'], df_2025['Precip_mm'], daily_mean['Precip_mm'], 'lightgreen', 'lightpink')

# 折线
ax.plot(df_2025['Date'], df_2025['Precip_mm'], color='blue', lw=1.5, label='2025日降水')
ax.plot(daily_mean['Date'], daily_mean['Precip_mm'], color='black', lw=1.2, linestyle='--', label='2020-2025日均值')
  • 蓝线:2025 年实际每日降水
  • 黑虚线:2020-2025 年平均每日降水
  • 渐变色带显示高于/低于均值的区域

8. 标注播种期和收获期

ax.axvline(pd.Timestamp('2025-06-01'), color='green', linestyle='--', lw=1, label='播种期')
ax.axvline(pd.Timestamp('2025-09-15'), color='orange', linestyle='--', lw=1, label='收获期')
  • 播种期:6 月 1 日
  • 收获期:9 月 15 日

9. 设置 X 轴与网格

ax.set_xlim(pd.Timestamp('2025-01-01'), pd.Timestamp('2025-12-31'))
ax.xaxis.set_major_locator(MonthLocator())
ax.xaxis.set_minor_locator(DayLocator(interval=1))
ax.xaxis.set_major_formatter(DateFormatter('%m-%d'))

plt.grid(True, color='grey', linestyle='--', linewidth=0.7, alpha=0.3)
ax.set_ylabel("降水量 (mm)")
  • 主刻度显示每月
  • 次刻度显示每天
  • 格式化为 MM-DD
  • 添加灰色网格

10. 自定义图例

legend_elements = [
    Patch(facecolor='lightgreen', edgecolor='lightgreen', alpha=0.5, label='高于六年均值'),
    Patch(facecolor='lightpink', edgecolor='lightpink', alpha=0.5, label='低于六年均值'),
    plt.Line2D([0], [0], color='blue', lw=1.5, label='2025日降水'),
    plt.Line2D([0], [0], color='black', lw=1.2, linestyle='--', label='2020-2025日均值'),
    plt.Line2D([0], [0], color='green', lw=1, linestyle='--', label='播种期'),
    plt.Line2D([0], [0], color='orange', lw=1, linestyle='--', label='收获期')
]

ax.legend(handles=legend_elements, loc="upper right", fontsize=8)
fig.tight_layout()
  • 自定义图例,包含色带和线条说明

11. 导出图片

plt.savefig("Precip_2025_vs_2020_2025_mean.png", dpi=300, bbox_inches='tight')
print("图片导出成功!")
plt.show()
  • 导出高分辨率 PNG 文件
  • 可直接用于报告或论文

🔹 总结

  1. 使用 Pandas 处理气象数据,计算每日均值
  2. 使用 Matplotlib 绘制折线和渐变色带
  3. 标注播种期和收获期,便于农业分析
  4. 自定义图例和网格,美化可视化结果
    在这里插入图片描述

更多推荐