# How to Use Herbie Visualization Aids and Cartopy Integration for Quick Map Plotting

> Quickly plot publication-ready weather maps with Herbie visualization aids and Cartopy integration. Use chained method calls for coastlines, borders, and scale bars.

- Repository: [Brian Blaylock/herbie](https://github.com/blaylockbk/herbie)
- Tags: how-to-guide
- Published: 2026-02-26

---

**Herbie's `EasyMap` class provides a streamlined wrapper around Cartopy that lets you create publication-ready weather maps with coastlines, borders, and scale bars using chained method calls.**

Herbie is an open-source Python package for downloading and processing weather model data. The `herbie.toolbox` module includes built-in visualization aids that simplify Cartopy integration, allowing you to generate geographic plots without boilerplate projection code. These tools are optional extras that require Cartopy but provide a high-level interface for rapid map generation.

## Core Components of Herbie's Cartopy Toolbox

### The EasyMap Class

The `EasyMap` class in [`src/herbie/toolbox/cartopy_tools.py`](https://github.com/blaylockbk/herbie/blob/main/src/herbie/toolbox/cartopy_tools.py) (starting at line 537) constructs a Cartopy `GeoAxesSubplot` and injects convenience methods directly into the axes object. It handles figure creation, projection setup, and default feature layers automatically.

### Feature Shortcuts and Geographic Layers

Herbie provides wrapped shortcuts for common Cartopy features. Methods like `COASTLINES()`, `BORDERS()`, `STATES()`, `OCEAN()`, `LAND()`, and `RIVERS()` wrap `cartopy.feature` calls and automatically apply your selected scale (`110m`, `50m`, or `10m`). The `COASTLINES` implementation appears at lines 96-102, while `STATES` is defined at lines 716-726 in [`cartopy_tools.py`](https://github.com/blaylockbk/herbie/blob/main/cartopy_tools.py).

### Projection and Extent Utilities

The `check_cartopy_axes` helper (line 261 in [`cartopy_tools.py`](https://github.com/blaylockbk/herbie/blob/main/cartopy_tools.py)) manages axes creation with custom coordinate reference systems. Extent utilities like `_adjust_extent`, `_center_extent`, and `_copy_extent` (starting at line 91) let you fine-tune map views with padding, city-centered extents, or copied boundaries between axes.

## Working with EasyMap for Rapid Map Generation

To begin, import the visualization aids from the toolbox:

```python
from herbie.toolbox import EasyMap, pc, ccrs, to_180, to_360

```

The `pc` variable provides a shortcut to `ccrs.PlateCarree()`, while `to_180` and `to_360` convert longitude conventions between -180° to 180° and 0° to 360° ranges.

Create a basic map with chained method calls:

```python
m = EasyMap(theme="dark", figsize=8).COASTLINES().STATES()
ax = m.ax
ax.set_title("Quick Map with Herbie")

```

Each feature method returns the `EasyMap` instance, enabling fluent chaining. The underlying Cartopy axes is accessible via the `.ax` attribute.

## Adding Scale Bars with cartopy_scalebar

For publication-quality maps, add a distance scale bar using the separate scale bar utility:

```python
from herbie.toolbox.cartopy_scalebar import scale_bar

scale_bar(ax, location=(0.05, 0.05), length=100, metres_per_unit=1000,
          unit_name="km", color="black")

```

The `scale_bar` function (defined at line 62 in [`src/herbie/toolbox/cartopy_scalebar.py`](https://github.com/blaylockbk/herbie/blob/main/src/herbie/toolbox/cartopy_scalebar.py)) handles geodesic calculations to ensure accurate distance representation regardless of projection distortion.

## Practical Code Examples

### Basic Map with Dark Theme

Create a styled base map with coastlines and US state borders using the dark theme:

```python
from herbie.toolbox import EasyMap

m = EasyMap(theme="dark", figsize=8).COASTLINES().STATES()
ax = m.ax
ax.set_title("US States – Dark Theme")

```

This leverages the `EasyMap.__init__` method (lines 546-562) which configures the theme and automatically adds coastlines when `add_coastlines=True`.

### Center on City with Scale Bar

Focus the map on a specific location and add a distance reference:

```python
from herbie.toolbox import EasyMap, pc
from herbie.toolbox.cartopy_scalebar import scale_bar

m = EasyMap(figsize=(10, 6)).center_extent(city="Denver", pad=0.5)
ax = m.ax

# Plot your data

# temp.plot(ax=ax, transform=pc, cmap="coolwarm")

scale_bar(ax, location=(0.05, 0.05), length=100, metres_per_unit=1000,
          unit_name="km", color="black")

```

The `center_extent` method (line 555 in [`cartopy_tools.py`](https://github.com/blaylockbk/herbie/blob/main/cartopy_tools.py)) handles geocoding and extent calculation with padding.

### Custom Lambert Conformal Projection

Use a specialized projection for regional weather maps:

```python
from herbie.toolbox import EasyMap, ccrs

lambert = ccrs.LambertConformal(central_longitude=-95, central_latitude=35)
m = EasyMap(crs=lambert, scale="50m", figsize=(12, 8))
m.OCEAN().LAND().ROADS().STATES()
ax = m.ax
ax.set_extent([-130, -60, 20, 55], crs=ccrs.PlateCarree())
ax.set_title("Lambert Conformal – US with Roads")

```

The `check_cartopy_axes` helper (line 261) manages the custom CRS setup and figure creation.

### Longitude Conversion for Datasets

Prepare gridded data for plotting by standardizing longitude conventions:

```python
import xarray as xr
from herbie.toolbox import to_180, pc

ds = xr.open_dataset("weather_data.nc")
ds = ds.assign_coords(lon=to_180(ds.lon))

m = EasyMap()
ds["temperature"].plot(ax=m.ax, transform=pc)

```

The `to_180` function (lines 55-64 in [`cartopy_tools.py`](https://github.com/blaylockbk/herbie/blob/main/cartopy_tools.py)) converts 0-360° longitudes to the -180-180° range required by many projections.

## Summary

- **Herbie's visualization aids** are located in [`src/herbie/toolbox/cartopy_tools.py`](https://github.com/blaylockbk/herbie/blob/main/src/herbie/toolbox/cartopy_tools.py) and provide a high-level wrapper around Cartopy functionality.
- The **`EasyMap` class** (line 537) creates pre-configured Cartopy axes with built-in methods for adding coastlines, borders, states, and land/ocean features.
- **Feature shortcuts** like `COASTLINES()`, `STATES()`, and `LAND()` automatically handle resolution scales (110m, 50m, 10m) and return the `EasyMap` instance for method chaining.
- **Extent utilities** including `center_extent()`, `adjust_extent()`, and `copy_extent()` (starting at line 91) simplify map navigation and view customization.
- The **`scale_bar` function** in [`cartopy_scalebar.py`](https://github.com/blaylockbk/herbie/blob/main/cartopy_scalebar.py) (line 62) adds accurate distance scalebars using geodesic calculations.
- **Longitude converters** `to_180` and `to_360` handle coordinate system transformations required for proper data alignment.

## Frequently Asked Questions

### Do I need to install Cartopy separately to use Herbie's visualization tools?

Yes, Cartopy is an optional dependency. While Herbie will install without it, attempting to import from `herbie.toolbox` will prompt you to install the Cartopy extra. You can install it with `pip install herbie-data[cartopy]` or `conda install cartopy` alongside Herbie.

### Can I use EasyMap with existing Cartopy axes or subplots?

Yes, the `check_cartopy_axes` helper function (line 261 in [`cartopy_tools.py`](https://github.com/blaylockbk/herbie/blob/main/cartopy_tools.py)) accepts existing axes objects. If you pass an existing Cartopy axes to `EasyMap` or use the toolbox functions directly, they will operate on that axes rather than creating a new figure.

### How do I change the resolution of map features like coastlines and borders?

Pass the `scale` parameter when creating an `EasyMap` instance (e.g., `EasyMap(scale="10m")`). This sets the resolution for all subsequent feature calls like `COASTLINES()` and `STATES()`. Valid options are `"110m"` (coarse), `"50m"` (intermediate), and `"10m"` (fine).

### What is the difference between `to_180` and `to_360` functions?

`to_180` (lines 55-64 in [`cartopy_tools.py`](https://github.com/blaylockbk/herbie/blob/main/cartopy_tools.py)) converts longitude coordinates from the 0° to 360° range to the -180° to 180° range, which is required by many Cartopy projections like PlateCarree. Conversely, `to_360` (lines 68-77) converts from -180° to 180° back to 0° to 360°, useful for aligning datasets that use different longitude conventions.