河南省 2025 年每日降水对比 2020-2025 年均值(Python 绘图教程)
·
河南省 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 文件
- 可直接用于报告或论文
🔹 总结
- 使用 Pandas 处理气象数据,计算每日均值
- 使用 Matplotlib 绘制折线和渐变色带
- 标注播种期和收获期,便于农业分析
- 自定义图例和网格,美化可视化结果

更多推荐


所有评论(0)