How to Use Herbie's Xarray Accessor for Enhanced Meteorological Data Analysis

Herbie's xarray accessor (.herbie) extends xarray Dataset objects with meteorology-specific methods for coordinate normalization, wind calculations, spatial subsetting, and domain geometry extraction, all accessible via ds.herbie.method().

The Herbie library simplifies downloading and reading GRIB2 weather model data, but its true analytical power emerges through the custom xarray accessor registered in src/herbie/accessors.py. When you open data via H.xarray(), the resulting Dataset automatically gains the .herbie namespace, providing a consistent API for common meteorological tasks without additional imports.

What Is Herbie's Xarray Accessor?

Herbie's accessor is registered using xr.register_dataset_accessor("herbie") at line 95 of src/herbie/accessors.py. This decorator attaches the HerbieAccessor class to every xarray Dataset created through Herbie's interface.

The accessor acts as a thin wrapper around reusable utilities and external libraries like MetPy, Cartopy, and Shapely. It uses @functools.cached_property for expensive calculations—such as coordinate reference system (CRS) creation—ensuring computational work is performed only once per dataset.

Core Methods for Coordinate and Spatial Analysis

Normalizing Longitudes with to_180 and to_360

Meteorological datasets often use longitude ranges of either [-180, 180] or [0, 360]. Herbie's accessor provides methods to re-wrap coordinates without manual indexing:

  • ds.herbie.to_180() — Re-wraps longitudes into the range [-180, 180]
  • ds.herbie.to_360() — Re-wraps longitudes into the range [0, 360]

These methods are implemented in src/herbie/accessors.py at lines 112-122 and handle the modular arithmetic required to shift coordinate values while preserving dataset integrity.

Calculating Grid Centers with center

The center property returns the geographic center of the grid as a tuple of (longitude, latitude). It lazily computes the mean of the latitude and longitude coordinates and caches the result:

lon_center, lat_center = ds.herbie.center

This is particularly useful when determining the map projection center or annotating spatial statistics. The implementation resides at lines 103-110 of src/herbie/accessors.py.

Extracting Domain Boundaries with polygon

The polygon property generates two Shapely polygons describing the domain boundary: one in latitude/longitude coordinates and another in the dataset's native projected coordinates. This is essential for spatial subsetting and domain visualization:

proj_poly, geo_poly = ds.herbie.polygon

The method uses the accessor's crs property to perform coordinate transformations and is implemented at lines 156-198 of src/herbie/accessors.py.

Meteorological Calculations and Wind Analysis

Computing Wind Speed and Direction with with_wind

The with_wind() method calculates wind speed and direction from available u* and v* wind components. It adds new variables with CF-style attributes, handling standard height levels including 10 m, 80 m, 100 m, and surface:

ds_with_wind = ds.herbie.with_wind()

# Access new variables: si10, wdir10, si80, wdir80, etc.

The method automatically detects available wind components and applies the appropriate calculations. Implementation details are found at lines 200-267 of src/herbie/accessors.py, with helper functions in src/herbie/toolbox/wind.py.

Cartopy CRS Integration via crs

The crs property builds a Cartopy coordinate reference system from CF metadata embedded in GRIB2 files. It lazily parses the dataset with MetPy (ds.metpy.parse_cf) and converts the resulting CRS to a Cartopy object:

cartopy_crs = ds.herbie.crs

# Use directly with cartopy: ax = plt.axes(projection=cartopy_crs)

This property is cached to avoid repeated MetPy parsing overhead and is implemented at lines 124-154 of src/herbie/accessors.py.

Spatial Subsetting and Point Extraction

Nearest Neighbor and Weighted Interpolation with pick_points

The pick_points() method provides advanced spatial extraction capabilities, delegating to the GridPointPicker class in src/herbie/pick_points.py. It supports both nearest-neighbor and distance-weighted interpolation:

import pandas as pd

stations = pd.DataFrame({
    "latitude": [40.0, 29.5, 42.3],
    "longitude": [-100.0, -105.0, -98.4],
    "stid": ["AA", "BB", "CC"]
})

# Nearest neighbor extraction

ds_points = ds.herbie.pick_points(stations, method="nearest")

# Weighted interpolation (k=4 by default)

ds_weighted = ds.herbie.pick_points(stations, method="weighted")

The method uses sklearn.neighbors.BallTree for efficient spatial indexing and can cache the index on disk using the default Herbie cache directory (herbie.config["default"]["save_dir"]). This dramatically speeds up repeated extractions on the same model grid.

Legacy Support with nearest_points

For backward compatibility, the accessor maintains a nearest_points() wrapper that calls the older herbie.nearest_points module. New code should prefer pick_points() for its enhanced performance and flexibility.

Practical Implementation Examples

The following workflow demonstrates loading HRRR model data and applying multiple accessor methods for comprehensive analysis:

import pandas as pd
import xarray as xr
from herbie import Herbie

# Load a GRIB2 dataset via Herbie

H = Herbie("2022-12-13 12:00", model="hrrr", product="sfc")
ds = H.xarray("TMP:2 m")  # Returns xarray.Dataset with .herbie accessor

# Normalize longitudes to [-180, 180] range

ds = ds.herbie.to_180()

# Compute wind speed and direction from u/v components

ds = ds.herbie.with_wind()

# Extract domain center for map annotations

lon_center, lat_center = ds.herbie.center

# Generate domain boundary polygons for spatial masking

proj_poly, geo_poly = ds.herbie.polygon

# Extract values at specific station locations

stations = pd.DataFrame({
    "latitude": [40.0, 29.5, 42.3],
    "longitude": [-100.0, -105.0, -98.4],
    "stid": ["AA", "BB", "CC"]
})
ds_points = ds.herbie.pick_points(stations, method="nearest")

All accessor methods are available immediately after loading data through Herbie, requiring no additional imports beyond the standard Herbie and xarray stack.

Summary

  • Herbie's xarray accessor (.herbie) is registered in src/herbie/accessors.py and automatically attaches to Datasets opened via H.xarray().
  • Coordinate utilities include to_180(), to_360(), and the center property for standardizing spatial references and calculating grid centers.
  • Domain geometry methods like polygon and crs leverage Cartopy and Shapely to create boundary polygons and coordinate reference systems from CF metadata.
  • Meteorological calculations such as with_wind() automatically derive wind speed and direction from u/v components with proper CF attributes.
  • Spatial extraction via pick_points() uses sklearn.neighbors.BallTree for efficient nearest-neighbor and weighted interpolation, with optional disk caching for repeated queries.

Frequently Asked Questions

How do I access Herbie's xarray accessor methods?

Once you load data using ds = H.xarray(...), the Dataset automatically has the .herbie namespace available. You can call methods directly via ds.herbie.method_name() without any additional imports. The accessor is registered in src/herbie/accessors.py using xr.register_dataset_accessor("herbie").

What is the difference between pick_points and nearest_points?

pick_points() is the modern, recommended method that delegates to GridPointPicker in src/herbie/pick_points.py, supporting both nearest-neighbor and weighted interpolation with sklearn.neighbors.BallTree indexing and disk caching. nearest_points() is a legacy wrapper maintained for backward compatibility that calls the older herbie.nearest_points module without the performance optimizations of the newer implementation.

Does the Herbie accessor modify the original xarray Dataset?

Methods like to_180(), to_360(), and with_wind() return new Dataset objects with modified coordinates or additional variables, following standard xarray conventions. Properties like center, crs, and polygon compute and cache values without altering the underlying dataset structure. The pick_points method returns a new Dataset containing extracted point data with attached metadata.

How does Herbie handle coordinate reference systems?

The crs property in src/herbie/accessors.py (lines 124-154) lazily parses CF metadata using MetPy's parse_cf() method and converts the result to a Cartopy CRS object. This is cached using @functools.cached_property to avoid repeated expensive parsing. The resulting CRS can be used directly with Cartopy for map projections or with the polygon property to transform domain boundaries between geographic and projected coordinates.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →