
1. 认识ERA5再分析数据与风速可视化第一次接触气象数据的朋友可能会问什么是ERA5简单来说它就是欧洲气象中心提供的天气历史百科全书。就像我们用手机查看过去一年的运动轨迹ERA5记录了地球大气层几十年来的详细状态。这次我们要用的10米极大风速数据就是其中记录地表附近风力强度的关键指标。为什么要选2024年1月和7月这两个月份正好代表北半球的冬夏两季。想象一下1月时北半球裹着棉袄瑟瑟发抖南半球却在享受阳光沙滩到了7月情况完全反转。这种季节反转会导致全球风场分布发生戏剧性变化而我们的任务就是用Python把这些变化直观地呈现出来。处理这类数据通常需要三个关键工具NetCDF文件处理气象数据的标准集装箱xarray库专门处理多维数据的瑞士军刀Cartopy库让地图绘制变得像搭积木一样简单我去年做过类似项目时最大的教训就是数据量太大导致内存爆炸。这次我会分享几个实测有效的内存优化技巧帮大家避开这个坑。2. 数据获取与前期准备2.1 注册CDS账号获取数据权限虽然原始文章提到需要特殊网络环境但其实有更稳定的方法。Copernicus Climate Data Store (CDS)提供了官方API接口注册过程比想象中简单访问CDS官网注册账号需要邮箱验证在个人页面找到API密钥选项卡复制给出的URL和密钥字符串这里有个小技巧把API信息保存在~/.cdsapirc文件里这样后续调用时就不用每次都输入密钥了。文件格式长这样url: https://cds.climate.copernicus.eu/api/v2 key: 12345:abcdefgh-1234-5678-9012-3456789012342.2 使用CDSAPI高效下载数据安装必备工具包pip install cdsapi xarray cartopy matplotlib下载2024年1月和7月数据的Python脚本import cdsapi c cdsapi.Client() for month in [01, 07]: c.retrieve( reanalysis-era5-single-levels, { product_type: reanalysis, variable: 10m_wind_gust_since_previous_post_processing, year: 2024, month: month, day: list(range(1,32)), time: [f{h:02d}:00 for h in range(24)], format: netcdf, }, fera5_wind_gust_2024_{month}.nc)实测发现两个省时技巧分批次下载不同月份避免单次请求太大被服务器拒绝添加area: [90, -180, -90, 180]参数可以只下载特定区域数据3. 数据解析与预处理3.1 理解NetCDF文件结构用xarray打开文件就像拆快递包裹import xarray as xr jan_data xr.open_dataset(era5_wind_gust_2024_01.nc) print(jan_data)你会看到类似这样的结构Dimensions: (time: 744, latitude: 721, longitude: 1440) Coordinates: * time (time) datetime64[ns] 2024-01-01 ... 2024-01-31T23:00:00 * latitude (latitude) float64 90.0 89.75 89.5 ... -89.75 -90.0 * longitude (longitude) float64 0.0 0.25 0.5 0.75 ... 359.25 359.5 359.75 Data variables: i10fg (time, latitude, longitude) float32 ...这里有个坑要注意经度范围是0-360°而Cartopy默认使用-180°到180°。后续绘图前需要转换jan_data jan_data.assign_coords(longitude(((jan_data.longitude 180) % 360) - 180)) jan_data jan_data.sortby(jan_data.longitude)3.2 计算月平均风速原始数据是每小时记录我们需要压缩成月平均monthly_mean jan_data.mean(dimtime)处理大文件时建议使用Dask分块计算jan_data xr.open_dataset(era5_wind_gust_2024_01.nc, chunks{time: 24})4. 地理可视化实战技巧4.1 基础地图绘制先上完整绘图代码import cartopy.crs as ccrs import matplotlib.pyplot as plt fig plt.figure(figsize(16, 8)) ax fig.add_subplot(111, projectionccrs.PlateCarree()) # 添加海岸线和国家边界 ax.coastlines(resolution50m, linewidth0.5) ax.add_feature(cartopy.feature.BORDERS, linestyle:, linewidth0.5) # 绘制风速填色图 mesh ax.pcolormesh(monthly_mean.longitude, monthly_mean.latitude, monthly_mean[i10fg], cmapviridis, transformccrs.PlateCarree()) # 添加色标和标题 plt.colorbar(mesh, label10m Wind Gust (m/s)) ax.set_title(January 2024 Global 10m Wind Gust, fontsize16)4.2 进阶美化技巧让专业级图表脱颖而出的三个秘诀自定义色标用plt.cm.get_cmap(RdYlBu_r)获取反转的红蓝渐变色更适合风速展示添加特殊区域标记# 标出赤道和回归线 ax.gridlines(draw_labelsTrue, xlocsrange(-180,181,30), ylocs[-23.5,0,23.5])风速阈值突出显示import numpy as np wind_data np.ma.masked_where(monthly_mean[i10fg] 15, monthly_mean[i10fg]) ax.contourf(monthly_mean.longitude, monthly_mean.latitude, wind_data, hatches[...], alpha0)5. 季节对比分析与解读5.1 并排对比图表把1月和7月结果放在一起观察fig, (ax1, ax2) plt.subplots(1, 2, figsize(20, 8), subplot_kw{projection: ccrs.PlateCarree()}) for ax, month, title in zip([ax1, ax2], [jan_data, jul_data], [January, July]): monthly_mean month.mean(dimtime) mesh ax.pcolormesh(monthly_mean.longitude, monthly_mean.latitude, monthly_mean[i10fg], cmapYlOrRd, vmin0, vmax20) ax.coastlines() ax.set_title(f{title} 2024 10m Wind Gust) plt.colorbar(mesh, ax[ax1, ax2], orientationhorizontal)5.2 典型区域风速变化选取几个关键区域分析数据# 定义区域边界 regions { North Atlantic: {lon: [-80, 0], lat: [30, 60]}, Southern Ocean: {lon: [0, 360], lat: [-60, -40]} } # 计算区域平均值 for name, box in regions.items(): mask ((jan_data.longitude box[lon][0]) (jan_data.longitude box[lon][1]) (jan_data.latitude box[lat][0]) (jan_data.latitude box[lat][1])) print(f{name} January mean: {jan_data[i10fg].where(mask).mean().values:.1f} m/s)6. 常见问题解决方案6.1 内存不足怎么办遇到大文件时试试这些方法使用Dask分块处理import dask.array as da data xr.open_dataset(big_file.nc, chunks{time: 24})降低空间分辨率coarsened data.coarsen(latitude2, longitude2, boundarytrim).mean()提取特定区域asia data.sel(latitudeslice(0, 60), longitudeslice(70, 140))6.2 图形渲染太慢优化绘图性能的技巧降低海岸线精度ax.coastlines(resolution110m)使用更快的投影ccrs.PlateCarree()比ccrs.Robinson()快得多先处理小范围测试再扩展到大区域7. 扩展应用方向这套方法稍作修改就能用于台风路径与风速关联分析风电场选址评估极端天气事件研究比如分析某次台风过程# 选取台风发生时间段 typhoon_period data.sel(timeslice(2024-07-15, 2024-07-20)) # 计算最大风速 peak_wind typhoon_period[i10fg].max(dimtime)最后提醒大家气象数据可视化就像做菜同样的食材数据可以做出不同风味的菜肴图表。多尝试不同的配色方案和展示形式找到最能突出你研究重点的呈现方式。我常用的配色网站是ColorBrewer里面的科学配色方案特别适合这类地理数据展示。