如何使用 Python 绘制 GFS grib2 数据?

How do I plot GFS grib2 data with Python?

我想在我的网站上放一张接下来几天的温度图表,而全球预报系统最能满足我的需要。如何在 matplotlib 中绘制 GRIB2 数据并根据绘图创建 PNG 图像?

我花了几个小时在互联网上搜索,询问知道如何做的人(他们根本没有帮助)但我不知道从哪里开始。 GFS 数据可以在这里找到:ftp://ftp.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/ 如果可能的话,我希望它是轻量级的并且不会丢失太多服务器 space.

当您考虑轻量化数据使用和存储时,您可能会考虑使用 GRIB 以外的其他数据形式。 GRIB 文件通常包含全球数据,当您只想为特定域绘图时,这是非常无用的。

我强烈建议使用来自 NOAA-NCEP opendap 数据服务器的数据。您可以使用 netCDF4 从该服务器获取数据。不幸的是,已知此服务器有时不稳定,这可能导致刷新 运行s and/or 格式错误的数据集出现延迟。尽管在 95% 的时间里,我都可以访问我需要的所有数据。

注意:由于新 运行 发布后的高流量,此数据服务器可能会变慢。可以在此处找到对数据服务器的访问:http://nomads.ncdc.noaa.gov/data.php?name=access#hires_weather_datasets

使用 Matplotlib 和 Basemap 工具包绘制数据非常容易。一些例子,包括 GFS 数据集的使用,可以在这里找到:http://matplotlib.org/basemap/users/examples.html

基本上,有两个步骤:

  1. 使用 wgrib 从 grib2 数据中提取选定的变量,并保存到 NetCDF 文件中。虽然有一些 API 例如 pygrib,但我发现直接使用命令行工具的错误更少。一些有用的链接:

安装:http://www.cpc.ncep.noaa.gov/products/wesley/wgrib2/compile_questions.html
技巧:http://www.ftp.cpc.ncep.noaa.gov/wd51we/wgrib2/tricks.wgrib2

例如提取温湿度:

wgrib2 test.grb2 -s | egrep '(:RH:2 m above ground:|:TMP:2 m above ground:)'|wgrib2 -i test.grb2 -netcdf test.nc
  1. 使用 Python 库处理 NetCDF 文件,示例代码可能如下所示:

    导入警告
    warnings.filterwarnings("ignore")
    将 matplotlib.pyplot 导入为 plt
    将 numpy 导入为 np
    将 pandas 导入为 pd
    % matplotlib 内联
    从 netCDF4 导入数据集
    从 mpl_toolkits.basemap 导入底图
    从 pyproj 导入 Proj
    将 matplotlib.cm 导入为 cm
    导入日期时间

    文件="test.nc"
    rootgrp = 数据集(文件,"r")
    x = rootgrp['longitude'][:] # 0-359, step = 1
    y = rootgrp['latitude'][:] # -90~90, step =1
    tmp = rootgrp['TMP_2maboveground'][:][0] # 形状 (181,360) dt = datetime.datetime(1970,1,1) + datetime.timedelta(seconds = rootgrp['time'][0])

    图 = plt.figure(dpi=150)
    m = Basemap(projection='mill',lat_ts=10,llcrnrlon=x.min(), urcrnrlon=x.max(),llcrnrlat=y.min(),urcrnrlat=y.max(),分辨率='c')

    xx, yy = m(*np.meshgrid(x,y))
    m.pcolormesh(xx,yy,tmp-273.15,shading='flat',cmap=plt.cm.jet)
    m.colorbar(位置='right')

    m.drawcoastlines()
    m.drawparallels(np.arange(-90.,120.,30.), labels=[1,0,0,0], fontsize=10)
    m.drawmeridians(np.arange(0.,360.,60.), labels=[0,0,0,1], fontsize=10)
    plt.title("{}, GFS, 温度 (C) ".format(dt.strftime('%Y-%m-%d %H:%M UTC')))
    plt.show()