Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I plot GFS grib2 data with Python?

I would like to have a chart with the temperatures for the following days on my website, and the Global Forecasting System meets my needs the most. How do I plot the GRIB2 data in matplotlib and create a PNG image from the plot?

I've spend hours of searching on the internet, asking people who do know how to do this (they where not helpfull at all) and I don't know where to start. GFS data can be found here: ftp://ftp.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/ If possible, I'd like it to be lightweight and without loosing too much server space.

like image 547
MetNL Development team Avatar asked Jun 01 '15 10:06

MetNL Development team


2 Answers

When you think lightweight about data usage and storage, you may consider to use other data forms than GRIB. GRIB-files usually contain worldwide data, which is pretty useless when you only want to plot for a specific domain.

I can strongly recommend to use data from the NOAA-NCEP opendap data server. You can gain data from this server using netCDF4. Unfortunately, this server is known to be unstable at some times which may causes delays in refreshing runs and/or malformed datasets. Although, in 95% of the time, I have acces to all the data I need.

Note: This data server may be slow due to high trafficking after a release of a new run. Acces to the data server can be found here: http://nomads.ncdc.noaa.gov/data.php?name=access#hires_weather_datasets

Plotting data is pretty easy with Matplotlib and Basemap toolkits. Some examples, including usage of GFS-datasets, can be found here: http://matplotlib.org/basemap/users/examples.html

like image 103
Wilfred Janssen Avatar answered Sep 18 '22 23:09

Wilfred Janssen


Basically, there are 2 steps:

  1. use wgrib to extract selected variables from grib2 data, and save into NetCDF file. Although there are some API such as pygrib, yet I found it less buggy to use the command line tool directly. some useful links:

install: http://www.cpc.ncep.noaa.gov/products/wesley/wgrib2/compile_questions.html
tricks: http://www.ftp.cpc.ncep.noaa.gov/wd51we/wgrib2/tricks.wgrib2

For example, extract temperature and humidity:

wgrib2 test.grb2 -s | egrep '(:RH:2 m above ground:|:TMP:2 m above ground:)'|wgrib2 -i test.grb2 -netcdf test.nc
  1. use Python libraries to process NetCDF files, example code may look like this:

    import warnings
    warnings.filterwarnings("ignore")
    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    % matplotlib inline
    from netCDF4 import Dataset
    from mpl_toolkits.basemap import Basemap
    from pyproj import Proj
    import matplotlib.cm as cm
    import datetime

    file = "test.nc"
    rootgrp = Dataset(file, "r")
    x = rootgrp['longitude'][:] # 0-359, step = 1
    y = rootgrp['latitude'][:] # -90~90, step =1
    tmp = rootgrp['TMP_2maboveground'][:][0] # shape(181,360) dt = datetime.datetime(1970,1,1) + datetime.timedelta(seconds = rootgrp['time'][0])

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

    xx, yy = m(*np.meshgrid(x,y))
    m.pcolormesh(xx,yy,tmp-273.15,shading='flat',cmap=plt.cm.jet)
    m.colorbar(location='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, Temperature (C) ".format(dt.strftime('%Y-%m-%d %H:%M UTC')))
    plt.show()

example figure

like image 26
Yuchao Jiang Avatar answered Sep 20 '22 23:09

Yuchao Jiang