Example 2: Reading a GRIB data set

GRIB (GRIdded Binary or General Regularly-distributed Information in Binary form) can be read with any of the following libraries or ways:

  • pygrib

  • xarray (with the PyNIO engine option)

  • PyNIO

  • wgrib2 or CDO to convert to NetCDF

In this example we'll use pygrib to read a WAVEWATCH III dataset, plot the parameter Significant Wave Height (SWH), and select a subregion.

The pygrib library can be installed in several ways: pip, conda (or whatever local package manager you're using for your python installation), or distutils (python setup.py).

  • As before, start by importing the required libraries
In [2]:
import matplotlib.pyplot as plt    # graphics library
import pygrib
import numpy as np                 # numeric python library
import cartopy.crs as ccrs         # cartographic coord reference system
import cartopy.feature as cfeature # features: land, borders, coastlines
  • Open the file and display the contents.

  • GRIB files are record-oriented, and pygrib stores the GRIB records in a list-like object.

  • You can access individual records by number or just iterate over the list.

In [3]:
gribs = pygrib.open('multi_1.glo_30mext.t00z.f000.grib2')

for grib in gribs:
    print(grib)
1:Wind speed:m s**-1 (instant):regular_ll:surface:level 1:fcst time 0 hrs:from 201808250000
2:Wind direction:Degree true (instant):regular_ll:surface:level 1:fcst time 0 hrs:from 201808250000
3:U component of wind:m s**-1 (instant):regular_ll:surface:level 1:fcst time 0 hrs:from 201808250000
4:V component of wind:m s**-1 (instant):regular_ll:surface:level 1:fcst time 0 hrs:from 201808250000
5:Significant height of combined wind waves and swell:m (instant):regular_ll:surface:level 1:fcst time 0 hrs:from 201808250000
6:Primary wave mean period:s (instant):regular_ll:surface:level 1:fcst time 0 hrs:from 201808250000
7:Primary wave direction:Degree true (instant):regular_ll:surface:level 1:fcst time 0 hrs:from 201808250000
8:Significant height of wind waves:m (instant):regular_ll:surface:level 1:fcst time 0 hrs:from 201808250000
9:Significant height of swell waves:m (instant):regular_ll:unknown:level 1 241:fcst time 0 hrs:from 201808250000
10:Significant height of swell waves:m (instant):regular_ll:unknown:level 2 241:fcst time 0 hrs:from 201808250000
11:Mean period of wind waves:s (instant):regular_ll:surface:level 1:fcst time 0 hrs:from 201808250000
12:Mean period of swell waves:s (instant):regular_ll:unknown:level 1 241:fcst time 0 hrs:from 201808250000
13:Mean period of swell waves:s (instant):regular_ll:unknown:level 2 241:fcst time 0 hrs:from 201808250000
14:Direction of wind waves:Degree true (instant):regular_ll:surface:level 1:fcst time 0 hrs:from 201808250000
15:Direction of swell waves:Degree true (instant):regular_ll:unknown:level 1 241:fcst time 0 hrs:from 201808250000
16:Direction of swell waves:Degree true (instant):regular_ll:unknown:level 2 241:fcst time 0 hrs:from 201808250000
  • You can select from the list of GRIB records with long name, short name, or any of the other keys in the file.

  • Note that the select method returns a list, even for a single message.

In [4]:
swh = gribs(shortName = 'swh',forecastTime = 0)[0]  # note single '=", not "=="
  • There's a lot of information in each GRIB record
In [5]:
for key in swh.keys(): # doing some python string formatting here
    print('{:>25} {}'.format(key, eval('swh.'+key)))
        parametersVersion 1
       UseEcmfConventions 1
   GRIBEX_boustrophedonic 0
                  hundred [100 100]
             globalDomain g
        GRIBEditionNumber 2
      tablesVersionLatest 20
             grib2divider 1000000
         angularPrecision 1000000
             missingValue 9999
               ieeeFloats 1
               isHindcast 0
           section0Length 16
               identifier GRIB
               discipline 10
            editionNumber 2
              totalLength 113928
            sectionNumber [1 3 3 4 5 6 7]
           section1Length 21
          numberOfSection [1 3 4 5 6 7]
                   centre kwbc
        centreDescription US National Weather Service - NCEP
                subCentre 0
            tablesVersion 2
                masterDir grib2/tables/[tablesVersion]
       localTablesVersion 1
significanceOfReferenceTime 1
                     year 2018
                    month 8
                      day 25
                     hour 0
                   minute 0
                   second 0
                 dataDate 20180825
                julianDay 2458355.5
                 dataTime 0
productionStatusOfProcessedData 0
      typeOfProcessedData fc
selectStepTemplateInterval 1
selectStepTemplateInstant 1
                 stepType instant
            setCalendarId 0
         deleteCalendarId 0
                 is_uerra 0
            sectionNumber [1 3 3 4 5 6 7]
 grib2LocalSectionPresent 0
            sectionNumber [1 3 3 4 5 6 7]
gridDescriptionSectionPresent 1
           section3Length 72
          numberOfSection [1 3 4 5 6 7]
   sourceOfGridDefinition 0
       numberOfDataPoints 241920
numberOfOctectsForNumberOfPoints 0
interpretationOfNumberOfPoints 0
                PLPresent 0
gridDefinitionTemplateNumber 0
gridDefinitionDescription Latitude/longitude. Also called equidistant cylindrical, or Plate Carree
          shapeOfTheEarth 6
scaleFactorOfRadiusOfSphericalEarth 0
scaledValueOfRadiusOfSphericalEarth 0
scaleFactorOfEarthMajorAxis 0
scaledValueOfEarthMajorAxis 0
scaleFactorOfEarthMinorAxis 0
scaledValueOfEarthMinorAxis 0
                   radius 6371229
                       Ni 720
                       Nj 336
basicAngleOfTheInitialProductionDomain 0
              mBasicAngle 0
          angleMultiplier 1
         mAngleMultiplier 1000000
 subdivisionsOfBasicAngle 0
             angleDivisor 1000000
 latitudeOfFirstGridPoint 90000000
longitudeOfFirstGridPoint 0
resolutionAndComponentFlags 48
resolutionAndComponentFlags1 0
resolutionAndComponentFlags2 0
 iDirectionIncrementGiven 1
 jDirectionIncrementGiven 1
         uvRelativeToGrid 0
resolutionAndComponentFlags6 0
resolutionAndComponentFlags7 0
resolutionAndComponentFlags8 0
ijDirectionIncrementGiven 1
  latitudeOfLastGridPoint -77500000
 longitudeOfLastGridPoint 359500000
      iDirectionIncrement 500000
      jDirectionIncrement 500000
             scanningMode 0
         iScansNegatively 0
         jScansPositively 0
    jPointsAreConsecutive 0
   alternativeRowScanning 0
         iScansPositively 1
            scanningMode5 0
            scanningMode6 0
            scanningMode7 0
            scanningMode8 0
                   g2grid [ 90.    0.  -77.5 359.5   0.5   0.5]
latitudeOfFirstGridPointInDegrees 90.0
longitudeOfFirstGridPointInDegrees 0.0
latitudeOfLastGridPointInDegrees -77.5
longitudeOfLastGridPointInDegrees 359.5
iDirectionIncrementInDegrees 0.5
jDirectionIncrementInDegrees 0.5
             latLonValues [  90.     0.  9999.  ...  -77.5  359.5 9999. ]
                latitudes [ 90.   90.   90.  ... -77.5 -77.5 -77.5]
               longitudes [  0.    0.5   1.  ... 358.5 359.  359.5]
        distinctLatitudes [ 90.   89.5  89.   88.5  88.   87.5  87.   86.5  86.   85.5  85.   84.5
  84.   83.5  83.   82.5  82.   81.5  81.   80.5  80.   79.5  79.   78.5
  78.   77.5  77.   76.5  76.   75.5  75.   74.5  74.   73.5  73.   72.5
  72.   71.5  71.   70.5  70.   69.5  69.   68.5  68.   67.5  67.   66.5
  66.   65.5  65.   64.5  64.   63.5  63.   62.5  62.   61.5  61.   60.5
  60.   59.5  59.   58.5  58.   57.5  57.   56.5  56.   55.5  55.   54.5
  54.   53.5  53.   52.5  52.   51.5  51.   50.5  50.   49.5  49.   48.5
  48.   47.5  47.   46.5  46.   45.5  45.   44.5  44.   43.5  43.   42.5
  42.   41.5  41.   40.5  40.   39.5  39.   38.5  38.   37.5  37.   36.5
  36.   35.5  35.   34.5  34.   33.5  33.   32.5  32.   31.5  31.   30.5
  30.   29.5  29.   28.5  28.   27.5  27.   26.5  26.   25.5  25.   24.5
  24.   23.5  23.   22.5  22.   21.5  21.   20.5  20.   19.5  19.   18.5
  18.   17.5  17.   16.5  16.   15.5  15.   14.5  14.   13.5  13.   12.5
  12.   11.5  11.   10.5  10.    9.5   9.    8.5   8.    7.5   7.    6.5
   6.    5.5   5.    4.5   4.    3.5   3.    2.5   2.    1.5   1.    0.5
   0.   -0.5  -1.   -1.5  -2.   -2.5  -3.   -3.5  -4.   -4.5  -5.   -5.5
  -6.   -6.5  -7.   -7.5  -8.   -8.5  -9.   -9.5 -10.  -10.5 -11.  -11.5
 -12.  -12.5 -13.  -13.5 -14.  -14.5 -15.  -15.5 -16.  -16.5 -17.  -17.5
 -18.  -18.5 -19.  -19.5 -20.  -20.5 -21.  -21.5 -22.  -22.5 -23.  -23.5
 -24.  -24.5 -25.  -25.5 -26.  -26.5 -27.  -27.5 -28.  -28.5 -29.  -29.5
 -30.  -30.5 -31.  -31.5 -32.  -32.5 -33.  -33.5 -34.  -34.5 -35.  -35.5
 -36.  -36.5 -37.  -37.5 -38.  -38.5 -39.  -39.5 -40.  -40.5 -41.  -41.5
 -42.  -42.5 -43.  -43.5 -44.  -44.5 -45.  -45.5 -46.  -46.5 -47.  -47.5
 -48.  -48.5 -49.  -49.5 -50.  -50.5 -51.  -51.5 -52.  -52.5 -53.  -53.5
 -54.  -54.5 -55.  -55.5 -56.  -56.5 -57.  -57.5 -58.  -58.5 -59.  -59.5
 -60.  -60.5 -61.  -61.5 -62.  -62.5 -63.  -63.5 -64.  -64.5 -65.  -65.5
 -66.  -66.5 -67.  -67.5 -68.  -68.5 -69.  -69.5 -70.  -70.5 -71.  -71.5
 -72.  -72.5 -73.  -73.5 -74.  -74.5 -75.  -75.5 -76.  -76.5 -77.  -77.5]
       distinctLongitudes [  0.    0.5   1.    1.5   2.    2.5   3.    3.5   4.    4.5   5.    5.5
   6.    6.5   7.    7.5   8.    8.5   9.    9.5  10.   10.5  11.   11.5
  12.   12.5  13.   13.5  14.   14.5  15.   15.5  16.   16.5  17.   17.5
  18.   18.5  19.   19.5  20.   20.5  21.   21.5  22.   22.5  23.   23.5
  24.   24.5  25.   25.5  26.   26.5  27.   27.5  28.   28.5  29.   29.5
  30.   30.5  31.   31.5  32.   32.5  33.   33.5  34.   34.5  35.   35.5
  36.   36.5  37.   37.5  38.   38.5  39.   39.5  40.   40.5  41.   41.5
  42.   42.5  43.   43.5  44.   44.5  45.   45.5  46.   46.5  47.   47.5
  48.   48.5  49.   49.5  50.   50.5  51.   51.5  52.   52.5  53.   53.5
  54.   54.5  55.   55.5  56.   56.5  57.   57.5  58.   58.5  59.   59.5
  60.   60.5  61.   61.5  62.   62.5  63.   63.5  64.   64.5  65.   65.5
  66.   66.5  67.   67.5  68.   68.5  69.   69.5  70.   70.5  71.   71.5
  72.   72.5  73.   73.5  74.   74.5  75.   75.5  76.   76.5  77.   77.5
  78.   78.5  79.   79.5  80.   80.5  81.   81.5  82.   82.5  83.   83.5
  84.   84.5  85.   85.5  86.   86.5  87.   87.5  88.   88.5  89.   89.5
  90.   90.5  91.   91.5  92.   92.5  93.   93.5  94.   94.5  95.   95.5
  96.   96.5  97.   97.5  98.   98.5  99.   99.5 100.  100.5 101.  101.5
 102.  102.5 103.  103.5 104.  104.5 105.  105.5 106.  106.5 107.  107.5
 108.  108.5 109.  109.5 110.  110.5 111.  111.5 112.  112.5 113.  113.5
 114.  114.5 115.  115.5 116.  116.5 117.  117.5 118.  118.5 119.  119.5
 120.  120.5 121.  121.5 122.  122.5 123.  123.5 124.  124.5 125.  125.5
 126.  126.5 127.  127.5 128.  128.5 129.  129.5 130.  130.5 131.  131.5
 132.  132.5 133.  133.5 134.  134.5 135.  135.5 136.  136.5 137.  137.5
 138.  138.5 139.  139.5 140.  140.5 141.  141.5 142.  142.5 143.  143.5
 144.  144.5 145.  145.5 146.  146.5 147.  147.5 148.  148.5 149.  149.5
 150.  150.5 151.  151.5 152.  152.5 153.  153.5 154.  154.5 155.  155.5
 156.  156.5 157.  157.5 158.  158.5 159.  159.5 160.  160.5 161.  161.5
 162.  162.5 163.  163.5 164.  164.5 165.  165.5 166.  166.5 167.  167.5
 168.  168.5 169.  169.5 170.  170.5 171.  171.5 172.  172.5 173.  173.5
 174.  174.5 175.  175.5 176.  176.5 177.  177.5 178.  178.5 179.  179.5
 180.  180.5 181.  181.5 182.  182.5 183.  183.5 184.  184.5 185.  185.5
 186.  186.5 187.  187.5 188.  188.5 189.  189.5 190.  190.5 191.  191.5
 192.  192.5 193.  193.5 194.  194.5 195.  195.5 196.  196.5 197.  197.5
 198.  198.5 199.  199.5 200.  200.5 201.  201.5 202.  202.5 203.  203.5
 204.  204.5 205.  205.5 206.  206.5 207.  207.5 208.  208.5 209.  209.5
 210.  210.5 211.  211.5 212.  212.5 213.  213.5 214.  214.5 215.  215.5
 216.  216.5 217.  217.5 218.  218.5 219.  219.5 220.  220.5 221.  221.5
 222.  222.5 223.  223.5 224.  224.5 225.  225.5 226.  226.5 227.  227.5
 228.  228.5 229.  229.5 230.  230.5 231.  231.5 232.  232.5 233.  233.5
 234.  234.5 235.  235.5 236.  236.5 237.  237.5 238.  238.5 239.  239.5
 240.  240.5 241.  241.5 242.  242.5 243.  243.5 244.  244.5 245.  245.5
 246.  246.5 247.  247.5 248.  248.5 249.  249.5 250.  250.5 251.  251.5
 252.  252.5 253.  253.5 254.  254.5 255.  255.5 256.  256.5 257.  257.5
 258.  258.5 259.  259.5 260.  260.5 261.  261.5 262.  262.5 263.  263.5
 264.  264.5 265.  265.5 266.  266.5 267.  267.5 268.  268.5 269.  269.5
 270.  270.5 271.  271.5 272.  272.5 273.  273.5 274.  274.5 275.  275.5
 276.  276.5 277.  277.5 278.  278.5 279.  279.5 280.  280.5 281.  281.5
 282.  282.5 283.  283.5 284.  284.5 285.  285.5 286.  286.5 287.  287.5
 288.  288.5 289.  289.5 290.  290.5 291.  291.5 292.  292.5 293.  293.5
 294.  294.5 295.  295.5 296.  296.5 297.  297.5 298.  298.5 299.  299.5
 300.  300.5 301.  301.5 302.  302.5 303.  303.5 304.  304.5 305.  305.5
 306.  306.5 307.  307.5 308.  308.5 309.  309.5 310.  310.5 311.  311.5
 312.  312.5 313.  313.5 314.  314.5 315.  315.5 316.  316.5 317.  317.5
 318.  318.5 319.  319.5 320.  320.5 321.  321.5 322.  322.5 323.  323.5
 324.  324.5 325.  325.5 326.  326.5 327.  327.5 328.  328.5 329.  329.5
 330.  330.5 331.  331.5 332.  332.5 333.  333.5 334.  334.5 335.  335.5
 336.  336.5 337.  337.5 338.  338.5 339.  339.5 340.  340.5 341.  341.5
 342.  342.5 343.  343.5 344.  344.5 345.  345.5 346.  346.5 347.  347.5
 348.  348.5 349.  349.5 350.  350.5 351.  351.5 352.  352.5 353.  353.5
 354.  354.5 355.  355.5 356.  356.5 357.  357.5 358.  358.5 359.  359.5]
                 gridType regular_ll
            sectionNumber [1 3 3 4 5 6 7]
           section4Length 34
          numberOfSection [1 3 4 5 6 7]
                       NV 0
           neitherPresent 0
productDefinitionTemplateNumber 0
      genVertHeightCoords 0
        parameterCategory 0
          parameterNumber 3
           parameterUnits m
            parameterName Significant height of combined wind waves and swell
  typeOfGeneratingProcess 2
        backgroundProcess 0
generatingProcessIdentifier 11
     hoursAfterDataCutoff 0
   minutesAfterDataCutoff 0
indicatorOfUnitOfTimeRange 1
                stepUnits 1
             forecastTime 0
                startStep 0
                  endStep 0
                stepRange 0
         stepTypeInternal instant
             validityDate 20180825
             validityTime 0
  typeOfFirstFixedSurface sfc
 unitsOfFirstFixedSurface unknown
  nameOfFirstFixedSurface Ground or water surface
scaleFactorOfFirstFixedSurface 0
scaledValueOfFirstFixedSurface 1
 typeOfSecondFixedSurface 255
unitsOfSecondFixedSurface unknown
 nameOfSecondFixedSurface Missing
scaleFactorOfSecondFixedSurface 0
scaledValueOfSecondFixedSurface 0
            pressureUnits hPa
              typeOfLevel surface
                    level 1
              bottomLevel 1
                 topLevel 1
        tempPressureUnits hPa
              paramIdECMF 140229
                  paramId 140229
            shortNameECMF swh
                shortName swh
                unitsECMF m
                    units m
                 nameECMF Significant height of combined wind waves and swell
                     name Significant height of combined wind waves and swell
               cfNameECMF unknown
                   cfName unknown
            cfVarNameECMF swh
                cfVarName swh
                modelName unknown
                 ifsParam 140229
                PVPresent 0
                 deletePV 1
          lengthOfHeaders 127
            sectionNumber [1 3 3 4 5 6 7]
           section5Length 23
          numberOfSection [1 3 4 5 6 7]
           numberOfValues 141321
dataRepresentationTemplateNumber 40
              packingType grid_jpeg
           referenceValue 0.0
      referenceValueError 1.1754943508222875e-38
        binaryScaleFactor 0
       decimalScaleFactor 2
             bitsPerValue 10
typeOfOriginalFieldValues 0
    typeOfCompressionUsed 0
   targetCompressionRatio 255
            sectionNumber [1 3 3 4 5 6 7]
           section6Length 30246
          numberOfSection [1 3 4 5 6 7]
          bitMapIndicator 0
            bitmapPresent 1
            sectionNumber [1 3 3 4 5 6 7]
           section7Length 83512
          numberOfSection [1 3 4 5 6 7]
              codedValues [0.56 0.57 0.58 ... 0.76 0.78 0.36]
                   values [[-- -- -- ... -- -- --]
 [-- -- -- ... -- -- --]
 [-- -- -- ... -- -- --]
 ...
 [-- -- -- ... -- -- --]
 [-- -- -- ... -- -- --]
 [-- -- -- ... -- -- --]]
                  maximum 9.25
                  minimum 0.0
                  average 2.467681165573415
          numberOfMissing 100599
        standardDeviation 1.5124010948213404
                 skewness 1.2054248217128987
                 kurtosis 1.411358951153586
               isConstant 0.0
   changeDecimalPrecision 2
         decimalPrecision 2
          setBitsPerValue 10
        getNumberOfValues 241920
            scaleValuesBy 1.0
           offsetValuesBy 0.0
              productType unknown
           section8Length 4
                 analDate 2018-08-25 00:00:00
                validDate 2018-08-25 00:00:00
  • Easiest way to get the data from the GRIB record is to use the object.data() method.

  • This returns the parameter array and the lat/lon coordinate arrays for the model grid.

In [6]:
data, lats, lons = swh.data()
  • Set up the plot figure as before and plot the SWH parameter
In [7]:
plt.figure(dpi = 90)
ax = plt.axes(projection = ccrs.Mercator()) # set up the axis projection
plt.pcolormesh(lons, lats, data, cmap = 'gist_ncar',transform = ccrs.PlateCarree())
cbar = plt.colorbar()
cbar.set_label(swh.shortName+' ('+swh.units+')')
ax.add_feature(cfeature.LAND)           # fill in the land areas
ax.coastlines()                         # use the default low-resolution coastline
gl = ax.gridlines(draw_labels = True)     # default is to label all axes.
gl.xlabels_top = False                  # turn off two of them.
gl.ylabels_right = False
plt.title(swh.name+'\n'+'Valid Date: '+swh.validDate.strftime('%Y%m%d'));
  • Now let's look closer at the data itself.
  • First off, what is this thing? You can identify the class of any python object with the type() function.
In [8]:
type(data)
Out[8]:
numpy.ma.core.MaskedArray
  • This is a numpy masked array. A masked array is the combination of a standard numpy.ndarray and a Boolean mask of the same shape. The numpy package ensures that the masked data points are excluded from computations.

  • As before, let's zoom in on Hawaii. We'll use the object.data() method for that, too. Remember that the "%" is the python symbol for modulo division.

In [9]:
data, lats, lons = swh.data(lon1 = -166%360, lon2 = -150%360,
                            lat1 = 14, lat2 = 27)
  • And now we can proceed to plot the swh parameter.
In [10]:
plt.figure(dpi = 90)
ax = plt.axes(projection = ccrs.Mercator())
plt.contourf(lons, lats, data, transform = ccrs.PlateCarree(), cmap='jet',
             levels = np.arange(np.floor(data.min()),np.ceil(data.max()),0.2))
plt.colorbar(label = swh.units)
ax.add_feature(cfeature.LAND,zorder = 1) # zorder will put the land on top 
ax.add_feature(cfeature.GSHHSFeature())
gl = ax.gridlines(draw_labels = True)       
gl.xlabels_top = False
gl.ylabels_right = False
gl.xlabel_style = {'size': 'x-small'}
gl.ylabel_style = {'size': 'x-small'}
plt.title(swh.name+'\n'+'Valid Date: '+swh.validDate.strftime('%Y%m%d'));

Next Example -- Reading a BUFR file