Plotting Guide
Nereus provides powerful plotting capabilities for visualizing unstructured model data on maps and as vertical transects.
2D Map Plotting
The plot() function is the primary tool for creating map visualizations:
import nereus as nr
fig, ax, interpolator = nr.plot(
data, lon, lat,
projection="rob",
cmap="viridis"
)
Basic Parameters
- dataarray-like
Array of values at each mesh point. Can be 1D or 2D. If xarray DataArray, coordinates may be extracted automatically.
- lon, latarray-like, optional
Longitude and latitude coordinates (in degrees). Can be 1D or 2D. If not provided, will attempt to extract from xarray DataArray.
Flexible Input Formats
Nereus accepts various input formats and automatically handles the conversion:
Data |
Lon/Lat |
Behavior |
|---|---|---|
1D |
1D (same size) |
Used directly (no warning) |
2D |
2D (same shape) |
All raveled to 1D (warning issued) |
1D |
2D |
Lon/lat raveled to match data (warning issued) |
2D |
1D |
Meshgrid created, then all raveled (warning issued) |
Example with 2D regular grid data:
# 2D data with 1D coordinates (like from NetCDF)
data_2d = np.random.rand(180, 360)
lon_1d = np.linspace(-179.5, 179.5, 360)
lat_1d = np.linspace(-89.5, 89.5, 180)
# Nereus automatically creates meshgrid internally
fig, ax, _ = nr.plot(data_2d, lon_1d, lat_1d)
Automatic Coordinate Extraction
When working with xarray DataArrays, coordinates can be extracted automatically:
import xarray as xr
# Load data with coordinates
ds = xr.open_dataset("ocean_data.nc")
temp = ds.temperature.isel(time=0, depth=0)
# No need to specify lon/lat - extracted automatically
fig, ax, _ = nr.plot(temp)
Nereus recognizes common coordinate names:
Longitude:
lon,longitude,x,nav_lon,glon,xt_ocean, etc.Latitude:
lat,latitude,y,nav_lat,glat,yt_ocean, etc.
You can also override one coordinate while extracting the other:
# Use custom lon, extract lat from xarray
fig, ax, _ = nr.plot(temp, lon=custom_lon)
- projectionstr, default “pc”
Map projection to use. See Map Projections below.
- extenttuple, optional
Map extent as
(lon_min, lon_max, lat_min, lat_max).- resolutionfloat or tuple, default 1.0
Target grid resolution. Either degrees (float) or
(nlon, nlat).
Appearance Parameters
- cmapstr, default “viridis”
Matplotlib colormap name.
- vmin, vmaxfloat, optional
Color scale limits. If not specified, uses data min/max.
- coastlinesbool, default True
Draw coastlines on the map.
- landbool, default False
Fill land areas with gray color.
- gridlinesbool, default False
Draw latitude/longitude gridlines.
- colorbarbool, default True
Add a colorbar to the plot.
- colorbar_labelstr, optional
Label for the colorbar.
- titlestr, optional
Plot title.
- figsizetuple, optional
Figure size as
(width, height)in inches.
Advanced Parameters
- axmatplotlib Axes, optional
Existing axes to plot on. Must be a Cartopy GeoAxes.
- interpolatorRegridInterpolator, optional
Pre-computed interpolator to reuse.
- method
"nearest"or"linear", default"nearest" Interpolation method.
"linear"uses Delaunay triangulation for smoother results (slower).- influence_radiusfloat, default 80000.0
Maximum distance (meters) from data points for interpolation.
- use_cachebool, default True
Use cached interpolator if available.
Map Projections
Nereus supports multiple map projections via short aliases:
Alias |
Projection |
Description |
|---|---|---|
|
PlateCarree |
Simple equirectangular projection. Good default for regional maps. |
|
Robinson |
Compromise projection for global maps. Good for world maps. |
|
Mercator |
Conformal projection. Preserves angles but distorts area at high latitudes. |
|
Mollweide |
Equal-area projection. Good for showing global distributions. |
|
North Polar Stereographic |
Centered on North Pole. Ideal for Arctic visualization. |
|
South Polar Stereographic |
Centered on South Pole. Ideal for Antarctic visualization. |
|
Orthographic |
View of Earth from space. Requires |
|
Lambert Conformal |
Good for mid-latitude regions with east-west extent. |
Examples with different projections:
# Global Robinson projection
nr.plot(data, lon, lat, projection="rob")
# Arctic view
nr.plot(data, lon, lat, projection="np")
# Antarctic view
nr.plot(data, lon, lat, projection="sp")
# Regional PlateCarree with extent
nr.plot(data, lon, lat, projection="pc",
extent=(-80, 0, 0, 60)) # North Atlantic
# Orthographic (globe view)
nr.plot(data, lon, lat, projection="ortho",
central_longitude=-30, central_latitude=45)
Polar Projections
For polar projections ("np" and "sp"), Nereus automatically:
Expands the data bounds to avoid edge artifacts
Uses circular map boundary
Sets appropriate extent
# Arctic sea ice
fig, ax, _ = nr.plot(
ice_concentration, lon, lat,
projection="np",
cmap="Blues",
vmin=0, vmax=1,
title="Arctic Sea Ice Concentration"
)
Reusing Interpolators
For efficiency when plotting multiple fields on the same mesh:
# First plot creates the interpolator
fig1, ax1, interp = nr.plot(temp, lon, lat, projection="rob")
# Subsequent plots reuse it (much faster)
fig2, ax2, _ = nr.plot(salt, lon, lat, projection="rob", interpolator=interp)
fig3, ax3, _ = nr.plot(speed, lon, lat, projection="rob", interpolator=interp)
Creating Animations
Efficiently create frame sequences:
import matplotlib.pyplot as plt
interpolator = None
for t in range(len(ds.time)):
data = ds.temp.isel(time=t, nz1=0).values
fig, ax, interpolator = nr.plot(
data, lon, lat,
projection="rob",
interpolator=interpolator, # Reuse after first frame
vmin=-2, vmax=30,
cmap="RdBu_r",
title=f"Time: {t}"
)
plt.savefig(f"frame_{t:04d}.png", dpi=150, bbox_inches="tight")
plt.close()
Vertical Transects
The transect() function creates vertical cross-sections along a great circle path:
fig, ax = nr.transect(
data_3d, lon, lat, depth,
start=(lon1, lat1),
end=(lon2, lat2),
n_points=200
)
Parameters
- dataarray-like
Data array with one of the following shapes:
(nlevels, npoints)- 2D array for unstructured meshes(nlevels, nlat, nlon)- 3D array for regular grids (automatically reshaped)
If xarray DataArray, coordinates may be extracted automatically.
- lon, latarray-like
Coordinate arrays. Can be:
1D arrays of same size (unstructured mesh coordinates)
1D arrays of different sizes (regular grid side coordinates - meshgrid created internally)
2D arrays of same shape (full coordinate arrays - raveled internally)
- deptharray-like
1D array of depth levels (positive downward).
- start, endtuple
Start and end points as
(lon, lat)tuples.- n_pointsint, default 100
Number of points along the transect.
- depth_limtuple, optional
Depth limits as
(min, max).- invert_depthbool, default True
Invert y-axis so depth increases downward (ocean convention). Set to False for atmosphere (height increases upward).
Flexible Input Formats
Nereus automatically handles various input combinations:
Data Shape |
Lon/Lat |
Behavior |
|---|---|---|
|
1D (same size) |
Used directly |
|
1D (different sizes) |
Data reshaped to 2D, meshgrid created for coordinates |
|
2D (same shape) |
Coordinates raveled to 1D |
Example with 3D regular grid data:
# 3D data with shape (depth, lat, lon)
# Common format from NetCDF files
temp = ds.temperature.values # shape: (42, 173, 360)
fig, ax = nr.transect(
temp,
ds.lon.values, # 1D: (360,)
ds.lat.values, # 1D: (173,)
ds.depth.values,
start=(-30, -60),
end=(-30, 70),
n_points=200
)
Example Transects
# Atlantic meridional transect
fig, ax = nr.transect(
ds.temp.isel(time=0),
ds.lon, ds.lat, ds.depth,
start=(-30, 60), # North Atlantic
end=(-30, -60), # South Atlantic
n_points=300,
cmap="RdBu_r",
vmin=-2, vmax=25,
depth_lim=(0, 5000),
colorbar_label="Temperature (°C)",
title="Atlantic Temperature Transect"
)
# Drake Passage transect
fig, ax = nr.transect(
ds.u.isel(time=0),
ds.lon, ds.lat, ds.depth,
start=(-70, -55),
end=(-55, -62),
cmap="RdBu_r",
depth_lim=(0, 3000),
colorbar_label="Zonal Velocity (m/s)"
)
Multi-Panel Figures
Combining multiple plots:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
fig = plt.figure(figsize=(14, 6))
# Temperature map
ax1 = fig.add_subplot(1, 2, 1, projection=ccrs.Robinson())
nr.plot(temp, lon, lat, ax=ax1, cmap="RdBu_r",
title="Temperature", colorbar_label="°C")
# Salinity map
ax2 = fig.add_subplot(1, 2, 2, projection=ccrs.Robinson())
nr.plot(salt, lon, lat, ax=ax2, cmap="viridis",
title="Salinity", colorbar_label="PSU")
plt.tight_layout()
Customizing Plots
The returned axes can be further customized:
fig, ax, _ = nr.plot(data, lon, lat, projection="rob")
# Add custom features
ax.set_title("Custom Title", fontsize=14, fontweight="bold")
# Add markers
ax.plot(-30, 45, 'r*', markersize=15, transform=ccrs.PlateCarree())
# Add text
ax.text(-30, 40, "Point A", transform=ccrs.PlateCarree(),
fontsize=10, ha="center")
# Customize gridlines
gl = ax.gridlines(draw_labels=True, linewidth=0.5, alpha=0.5)
gl.top_labels = False
gl.right_labels = False
Handling Missing Data
Nereus handles NaN values automatically:
# NaN values in data are preserved in output
data_with_nans = np.where(land_mask, np.nan, data)
nr.plot(data_with_nans, lon, lat)
The influence_radius parameter also creates a natural mask where no source data exists:
# Smaller influence radius = tighter mask around data
nr.plot(data, lon, lat, influence_radius=50000) # 50 km
# Larger influence radius = fills more gaps
nr.plot(data, lon, lat, influence_radius=200000) # 200 km