pygrib
Pygrib is a Python module designed for reading and writing GRIB (General Regularly-distributed Information in Binary form) files, which is the World Meteorological Organization (WMO) standard format for weather data. It provides a high-level interface to the ECMWF ECCODES C library, supporting both GRIB edition 1 and edition 2. The library is currently at version 2.1.8 and sees active development with regular releases.
Warnings
- gotcha Installation can be complex due to the underlying ECCODES C library dependency. On some systems (especially Windows or when building from source), manual installation of ECCODES and setting environment variables like `ECCODES_DEFINITION_PATH` (e.g., to `$CONDA_PREFIX/Library/share/eccodes/definitions`) might be necessary to avoid errors like 'boot.def cannot be found'. Pip/conda generally attempt to handle this automatically, but issues can arise.
- gotcha On Anaconda environments, compatibility issues with newer HDF5 library versions (e.g., 1.10.0) have caused `ImportError` due to linking problems with the `ecmwf_grib` dependency.
- gotcha Pygrib has limited capabilities for writing GRIB files. You can modify the contents (e.g., data values) of an *existing* GRIB message and write it, but you cannot create an entirely new GRIB file from scratch.
- gotcha When modifying GRIB2 message values (`grb['values']`), the `orderOfSpatialDifferencing` key might be reset to a default (e.g., 0), which can lead to the output GRIB2 file being considered 'unusable' by other GRIB tools (like `wgrib2`).
- breaking Compatibility issues have been reported with newer versions of Cython (e.g., > 0.29 and >= 3.1), which might lead to build failures if Cython is not pinned to a compatible version during installation.
Install
-
pip install pygrib -
conda install -c conda-forge pygrib
Imports
- pygrib
import pygrib
Quickstart
import pygrib
import os
# Create a dummy GRIB file for demonstration purposes
# In a real scenario, you would have an actual GRIB file.
# This example can't create a GRIB file from scratch due to pygrib's limitations,
# so we simulate reading one.
# For actual usage, replace 'sample.grib2' with your file path.
# If you don't have one, consider downloading a small sample GRIB file from a meteorological data source.
# Example: A minimalist GRIB file (not functional for this code but demonstrates intent)
# For this example, assume 'sample.grib2' exists and contains at least one message.
# Placeholder for a real GRIB file path
grib_file_path = os.environ.get('GRIB_SAMPLE_PATH', 'sample.grib2')
# Create a dummy file if it doesn't exist for the example to run without FileNotFoundError
if not os.path.exists(grib_file_path):
print(f"Warning: '{grib_file_path}' not found. Cannot run quickstart without a GRIB file.\n" \
"Please set the GRIB_SAMPLE_PATH environment variable or create 'sample.grib2'.")
# Optionally create a minimal (non-functional) placeholder to prevent immediate crash
with open(grib_file_path, 'wb') as f:
f.write(b'GRIB-DUMMY-FILE') # Not a valid GRIB file, but prevents FileNotFoundError
try:
grbs = pygrib.open(grib_file_path)
# Read the first message
# .read() returns a list of messages, so we take the first element.
grb = grbs.read(1)[0]
print(f"GRIB Message 1: {grb}")
print(f"Short Name: {grb.shortName}")
print(f"Parameter Name: {grb.name}")
print(f"Units: {grb.units}")
print(f"Valid Date: {grb.validDate}")
# Get data values (as a numpy array)
data = grb.values
print(f"Data shape: {data.shape}")
print(f"Data min/max: {data.min()}/{data.max()}")
# Get latitudes and longitudes
lats, lons = grb.latlons()
print(f"Latitudes shape: {lats.shape}, Longitudes shape: {lons.shape}")
grbs.close()
except Exception as e:
print(f"An error occurred: {e}")
if 'not a GRIB file' in str(e):
print("This often means the GRIB_SAMPLE_PATH points to an invalid or empty file.")
if os.path.exists(grib_file_path) and os.path.getsize(grib_file_path) < 100: # heuristic for dummy file
print("The quickstart created a dummy file; please provide a real GRIB file for full functionality.")