3. 数据探索与可视化:用 Matplotlib 和 Cartopy 绘制气象要素时空分布图、时间序列图

气象数据拿到手,第一件事是什么?

我个人习惯,不是急着建模,而是先画图。数据长什么样,有没有异常值,空间分布是否合理,时间序列有没有跳变——这些信息,图上一眼就能看出来。说白了,可视化是数据探索的“第一道安检”。

这一章,我们就来聊聊怎么用 Python 里的 Matplotlib 和 Cartopy 把气象要素的时空分布和时间序列画得既专业又漂亮。

3.1 为什么可视化对气象数据这么重要?

你想想看,气象数据本质上是四维的:经度、纬度、高度、时间。光看数字表格,你根本看不出台风眼在哪,也看不出冷锋推进的速度。我曾在项目里遇到过一份再分析数据,温度场看起来一切正常,但一画图就发现——北极上空有个诡异的“热斑”,后来排查发现是数据插值时边界处理出了问题。要是没画图,这个坑就踩进去了。

所以,数据探索阶段的可视化,核心目标就三个:

  • 发现异常:比如缺测值、跳变点、空间不连续
  • 理解分布:气象要素的均值、方差、极值区域在哪
  • 验证直觉:比如夏季高温是否集中在副高控制区

3.2 工具准备:Matplotlib + Cartopy 的黄金组合

Matplotlib 是 Python 可视化的基石,但画地图时它有个短板——默认的投影是笛卡尔坐标,没法直接画经纬度。Cartopy 就是来补这块短板的。它提供了丰富的地图投影、海岸线、国界线等地理要素。

安装很简单:

pip install matplotlib cartopy

嗯,这里要注意:Cartopy 依赖 GEOS 库,Windows 用户建议用 conda 安装,省得折腾。

3.3 绘制气象要素空间分布图(填色图)

空间分布图,最常见的就是填色图(contourf)。比如我们要画某一天全球地表温度的分布。

先看代码:

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import numpy as np

# 模拟数据:经度0-360,纬度-90到90
lon = np.linspace(0, 360, 360)
lat = np.linspace(-90, 90, 180)
lon2d, lat2d = np.meshgrid(lon, lat)

# 模拟温度场:赤道热,两极冷
temp = 30 * np.cos(np.deg2rad(lat2d)) + 5 * np.sin(np.deg2rad(lon2d * 3))

# 创建画布,使用PlateCarree投影
fig = plt.figure(figsize=(12, 6))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())

# 添加地理要素
ax.add_feature(cfeature.COASTLINE, linewidth=0.5)
ax.add_feature(cfeature.BORDERS, linewidth=0.3, alpha=0.5)

# 绘制填色图
cf = ax.contourf(lon, lat, temp, transform=ccrs.PlateCarree(),
                 cmap='RdBu_r', levels=20)

# 添加colorbar
plt.colorbar(cf, ax=ax, orientation='horizontal', pad=0.05,
             label='Temperature (°C)')

# 设置范围
ax.set_global()
ax.set_title('Global Surface Temperature Distribution', fontsize=14)

plt.show()

这段代码里,有几点我想特别说一下:

  • 投影选择:PlateCarree 是最简单的等距圆柱投影,适合全球概览。如果是区域分析,我常用 Lambert 或 Mercator。
  • transform 参数:这个必须和数据本身的投影一致。数据是经纬度,就用 PlateCarree。我见过有人忘了加 transform,结果填色图位置全偏了。
  • 色标选择:温度用 RdBu_r(红蓝反转),降水用 Blues 或 viridis。别用彩虹色,容易误导。
小技巧:如果数据范围是 0-360 经度,而你想显示 -180 到 180,可以用 ax.set_extent([-180, 180, -90, 90]) 来裁剪。Cartopy 会自动处理经度转换。

3.4 绘制时间序列图:看趋势和周期

空间分布图告诉你“哪里热”,时间序列图告诉你“怎么变”。

比如,我们想看看北京2023年逐日平均气温的变化:

import pandas as pd
import matplotlib.pyplot as plt

# 模拟时间序列数据
dates = pd.date_range('2023-01-01', '2023-12-31', freq='D')
temp_beijing = 15 + 25 * np.sin(2 * np.pi * dates.dayofyear / 365) + np.random.randn(365) * 3

fig, ax = plt.subplots(figsize=(12, 5))
ax.plot(dates, temp_beijing, color='#E74C3C', linewidth=0.8, alpha=0.7)
ax.scatter(dates[::10], temp_beijing[::10], color='#C0392B', s=10, alpha=0.5)

ax.set_xlabel('Date')
ax.set_ylabel('Temperature (°C)')
ax.set_title('Daily Mean Temperature in Beijing (2023)')
ax.grid(True, linestyle='--', alpha=0.3)

plt.tight_layout()
plt.show()

画时间序列,我一般会注意三点:

  • 数据密度:如果数据点太多(比如分钟级),用折线加散点会显得杂乱。可以只画折线,或者用滚动平均平滑一下。
  • 异常值标记:我曾经在处理某次台风数据时,发现气压序列里有个 -9999 的值,画图时直接显示为一条垂直线。后来我养成了习惯——画图前先检查缺测值。
  • 季节分解:如果序列有明显的年周期,可以用 statsmodels 的 seasonal_decompose 把趋势、季节、残差分开画。

3.5 时空结合:Hovmöller 图

有时候,我们想同时看时间和空间的变化。比如,某个经度带上温度随纬度和时间的变化。这时候 Hovmöller 图就派上用场了。

说白了,Hovmöller 图就是把经度或纬度作为 y 轴,时间作为 x 轴,用填色表示要素值。这在分析热带波动、MJO( Madden-Julian 振荡)时非常常见。

# 模拟Hovmöller数据:纬度0-60N,时间365天
lat_hov = np.linspace(0, 60, 60)
time_hov = np.arange(365)
lat2d_hov, time2d_hov = np.meshgrid(lat_hov, time_hov)

# 模拟一个向东传播的信号
signal = 10 * np.sin(2 * np.pi * (time2d_hov / 30 - lat2d_hov / 20))

fig, ax = plt.subplots(figsize=(10, 6))
cf = ax.contourf(time_hov, lat_hov, signal.T, cmap='RdBu_r', levels=20)
ax.set_xlabel('Day of Year')
ax.set_ylabel('Latitude (°N)')
ax.set_title('Hovmöller Diagram: Temperature Anomaly')
plt.colorbar(cf, ax=ax, label='Anomaly (°C)')
plt.show()

你看,这种图能很直观地看出信号是向东还是向西传播。斜率的正负就代表传播方向。

3.6 避坑指南:我踩过的那些坑

做气象可视化这么多年,有些坑我替你们踩过了,直接说重点:

  • 投影不匹配:数据是经纬度,但画布用了 Orthographic 投影,结果数据点全堆在中心。记住:数据投影和画布投影要一致,或者用 transform 显式指定。
  • 色标误导:有一次我用 jet 色标画降水,结果把小雨区画成了亮红色,看起来像极端暴雨。后来我改用统一的色标规范,比如降水用 Blues,温度用 RdBu。
  • 坐标轴标签被截断:画地图时,经度标签有时会跑到图外面。解决办法是用 ax.set_extent 留出边距,或者手动调整标签位置。
  • 内存爆炸:画高分辨率全球数据时,contourf 可能会卡死。我的经验是:先降采样到 1°×1°,画完草图确认无误后,再用高分辨率出图。
注意:Cartopy 0.18 版本之后,cfeature.NaturalEarthFeature 的下载方式有变化。如果第一次运行报错,检查网络连接,或者手动下载 shapefile 放到指定目录。

3.7 本章知识体系

为了让你更清晰地理解本章的逻辑,我画了一张流程图:

数据探索与可视化知识体系 气象数据可视化 空间分布图 时间序列图 时空结合图 填色图 (contourf) 投影选择 · 色标规范 · 地理要素 折线图 + 散点图 趋势分析 · 异常检测 · 季节分解 Hovmöller 图 经度-时间 · 纬度-时间 · 传播方向 核心目标:发现异常 · 理解分布 · 验证直觉 工具:Matplotlib + Cartopy + Pandas

3.8 实战建议

学完这些,我建议你找一份真实的气象数据练手。比如 ERA5 的月平均数据,或者 NOAA 的站点观测数据。从最简单的填色图开始,慢慢加上海岸线、国界线、色标、标题。然后画时间序列,看看有没有明显的年周期或趋势。

记住,可视化不是为了好看,是为了发现问题。我每次画完图,都会问自己三个问题:

  1. 这张图告诉我什么信息?
  2. 有没有任何异常或不符合物理规律的地方?
  3. 如果我要给非专业人士看,他们能看懂吗?

嗯,做到这三点,你的数据探索就算到位了。


专注资料整理