当前位置:首页>python>Python | GRIB格式数据处理及绘图

Python | GRIB格式数据处理及绘图

  • 2026-10-21 13:28:30
Python | GRIB格式数据处理及绘图

简介

GRIB(General Regularly distributed Information in Binary form)是世界气象组织(WMO)标准化的二进制格式,专门用于存储和传输气象、海洋等领域的网格化物理量数据,以其高效压缩和灵活的元数据结构,成为全球气象业务与科研的通用标准。然而,面对这种专业格式,许多人在第一步“读取数据”时就可能陷入困境——复杂的二进制结构、令人眼花缭乱的参数编码、多层次的海量数据……本文介绍如何使用 pygrib 轻松读取 GRIB 文件,提取你需要的气象要素,并经过简单处理进行绘图!

代码

import pygribimport numpy as npimport matplotlib.pyplot as pltimport cartopy.crs as ccrsimport cartopy.feature as cfeaturefrom datetime import datetimedef plot_t2m_fixed(grib_file, target_date='1979-01-01'):"""    2m 温度    """    grbs = pygrib.open(grib_file)    found_data = []    target_dt = datetime.strptime(target_date, '%Y-%m-%d').date()for grb in grbs:if (grb.parameterName == '2 metre temperature' and                grb.typeOfLevel == 'surface' and                grb.level == 0):            data_time = grb.validDate# 检查日期是否匹配if data_time.date() == target_dt:print(f"✓ 找到匹配数据: 时间 {data_time}")                found_data.append({'grb': grb,'time': data_time                })if not found_data:print(f"未找到 {target_date} 的数据")        grbs.close()return None, None, None    grb = found_data[0]['grb']    data_time = found_data[0]['time']print(f"使用数据时间: {data_time}")# 获取数据    t2m_data = grb.values    lats, lons = grb.latlons()print(f"数据形状: {t2m_data.shape}")print(f"纬度范围: {lats.min():.2f} 到 {lats.max():.2f}")print(f"经度范围: {lons.min():.2f} 到 {lons.max():.2f}")print(f"温度范围: {t2m_data.min():.2f}K 到 {t2m_data.max():.2f}K")# 转换为摄氏度    t2m_data_celsius = t2m_data - 273.15    unit = "°C"# 区域裁剪    lat_range = (20, 50)    lon_range = (100, 130)    lat_mask = (lats >= lat_range[0]) & (lats <= lat_range[1])    lon_mask = (lons >= lon_range[0]) & (lons <= lon_range[1])    region_mask = lat_mask & lon_mask    region_lats = lats[region_mask]    region_lons = lons[region_mask]    region_t2m = t2m_data_celsius[region_mask]# 计算统计    region_mean = np.mean(region_t2m)    region_max = np.max(region_t2m)    region_min = np.min(region_t2m)print(f"\n区域统计 ({target_date}):")print(f"平均温度: {region_mean:.2f}{unit}")print(f"最高温度: {region_max:.2f}{unit}")print(f"最低温度: {region_min:.2f}{unit}")# 绘图    plot_temperature_map(region_lons, region_lats, region_t2m, data_time, unit,                         lat_range, lon_range)    grbs.close()return region_t2m, region_lats, region_lonsdef plot_temperature_map(lons, lats, data, data_time, unit, lat_range, lon_range):"""    绘制温度分布图    """    fig = plt.figure(figsize=(12, 8))    ax = plt.axes(projection=ccrs.PlateCarree())# 设置地图范围    ax.set_extent([lon_range[0], lon_range[1], lat_range[0], lat_range[1]],                  crs=ccrs.PlateCarree())# 添加地图要素    ax.add_feature(cfeature.COASTLINE, linewidth=0.8)    ax.add_feature(cfeature.BORDERS, linewidth=0.5)    ax.add_feature(cfeature.OCEAN, color='lightblue', alpha=0.3)    ax.add_feature(cfeature.LAND, color='lightgray', alpha=0.1)# 添加网格线    gl = ax.gridlines(draw_labels=True, alpha=0.5, linestyle='--')    gl.top_labels = False    gl.right_labels = False    gl.xlabel_style = {'size': 10}    gl.ylabel_style = {'size': 10}# 创建散点图    scatter = ax.scatter(lons, lats, c=data,                         cmap='RdBu_r', s=15, alpha=0.8,                         vmin=np.floor(np.min(data)), vmax=np.ceil(np.max(data)),                         transform=ccrs.PlateCarree())# 添加颜色条    cbar = plt.colorbar(scatter, ax=ax, orientation='vertical',                        shrink=0.8, pad=0.05)    cbar.set_label(f'2m Temperature ({unit})', fontsize=12)# 设置标题    title_date = data_time.strftime('%Y-%m-%d %H:%M UTC')    plt.title(f'2m Temperature - {title_date}\n'              f'Region Mean: {np.mean(data):.2f}{unit}',              fontsize=14, fontweight='bold')    plt.tight_layout()    plt.savefig('test_GRIB.png', dpi=600, bbox_inches='tight')    plt.show()# 执行绘图try:    data, lats, lons = plot_t2m_fixed('t2m_1979_hourly.grib',        target_date='1979-12-01'    )if data is not None:print("绘图完成!")else:print("未找到数据")except Exception as e:print(f"处理文件时出错: {e}")    import traceback    traceback.print_exc()

结果

最新文章

随机文章