Plotting Module (marEx.plotX)

The marEx.plotX module provides visualisation functions for marine extreme events through an xarray accessor pattern. It automatically detects grid types and applies appropriate visualisation methods for both structured and unstructured grids.

Overview

The plotting module implements an xarray accessor that seamlessly integrates with xarray DataArrays to provide specialised plotting capabilities. The system automatically detects whether data is on a structured (regular lat/lon) or unstructured (irregular mesh) grid and applies the appropriate plotting method.

Key Features:

  • Automatic Grid Detection: Detects structured vs. unstructured grids automatically

  • xarray Integration: Access via .plotX accessor on DataArrays

  • Flexible Configuration: Comprehensive plotting options via PlotConfig

  • Animation Support: Built-in animation capabilities for time series data

  • Memory Efficient: Global caching for triangulation and spatial indexing

Main Components

PlotConfig([title, var_units, issym, cmap, ...])

Configuration class for plot parameters

specify_grid([grid_type, fpath_tgrid, ...])

Set the global grid specification that will be used by all plotters.

PlotXAccessor(xarray_obj)

Xarray accessor for plotX functionality with support for custom dimensions and coordinates.

Grid Detection and Configuration

Grid Type Detection

The plotting system automatically detects grid types based on coordinate structure:

  • Structured Grids: Have separate latitude and longitude dimensions (e.g., lat, lon)

  • Unstructured Grids: Have a single spatial dimension (e.g., ncells) with lat/lon as coordinates

marEx.plotX.specify_grid(grid_type=None, fpath_tgrid=None, fpath_ckdtree=None)[source]

Set the global grid specification that will be used by all plotters.

Parameters:
  • grid_type (str | None) – str, either ‘gridded’ or ‘unstructured’. If specified, this will be used as the primary method to determine grid type.

  • fpath_tgrid (str | Path | None) – Path to the triangulation grid file

  • fpath_ckdtree (str | Path | None) – Path to the pre-computed KDTree indices directory

Return type:

None

Configuration Class

class marEx.plotX.PlotConfig(title=None, var_units='', issym=False, cmap=None, cperc=None, clim=None, show_colorbar=True, grid_lines=True, grid_labels=False, dimensions=None, coordinates=None, norm=None, plot_IDs=False, extend='both', verbose=None, quiet=None, projection=None, framerate=10)[source]

Bases: object

Configuration class for plot parameters

Parameters:
title

Plot title

Type:

str | None

var_units

Variable units for colorbar label

Type:

str

issym

Whether data is symmetric (centers colormap at 0)

Type:

bool

cmap

Colormap name or ListedColormap object

Type:

str | matplotlib.colors.ListedColormap | None

cperc

Percentile range for automatic color limits [min, max]

Type:

List[int]

clim

Manual color limits (vmin, vmax)

Type:

Tuple[float, float] | None

show_colorbar

Whether to display colorbar

Type:

bool

grid_lines

Whether to display grid lines

Type:

bool

grid_labels

Whether to display grid labels

Type:

bool

dimensions

Mapping of conceptual to actual dimension names

Type:

Dict[str, str]

coordinates

Mapping of conceptual to actual coordinate names

Type:

Dict[str, str]

norm

Custom normalization (BoundaryNorm or Normalize)

Type:

matplotlib.colors.BoundaryNorm | matplotlib.colors.Normalize | None

plot_IDs

Whether to plot object IDs with random colors

Type:

bool

extend

Colorbar extension (‘neither’, ‘both’, ‘min’, ‘max’)

Type:

str

verbose

Enable verbose logging

Type:

bool | None

quiet

Enable quiet logging

Type:

bool | None

projection

Cartopy projection for map plots

Type:

Any | None

framerate

Frames per second for animations (default 10)

Type:

int

title: str | None = None
var_units: str = ''
issym: bool = False
cmap: str | ListedColormap | None = None
cperc: List[int] = None
clim: Tuple[float, float] | None = None
show_colorbar: bool = True
grid_lines: bool = True
grid_labels: bool = False
dimensions: Dict[str, str] = None
coordinates: Dict[str, str] = None
norm: BoundaryNorm | Normalize | None = None
plot_IDs: bool = False
extend: str = 'both'
verbose: bool | None = None
quiet: bool | None = None
projection: Any | None = None
framerate: int = 10
__post_init__()[source]

Initialise default values and configure logging.

Return type:

None

__init__(title=None, var_units='', issym=False, cmap=None, cperc=None, clim=None, show_colorbar=True, grid_lines=True, grid_labels=False, dimensions=None, coordinates=None, norm=None, plot_IDs=False, extend='both', verbose=None, quiet=None, projection=None, framerate=10)
Parameters:
Return type:

None

Basic Usage

Simple Plotting

import xarray as xr
import marEx

# Load data
data = xr.open_dataset('example.nc').temperature

# Basic plot - automatic grid detection
fig, ax, im = data.plotX.single_plot(marEx.PlotConfig())

Advanced Configuration

# Custom plot configuration
config = marEx.PlotConfig(
    title='Sea Surface Temperature',
    var_units='°C',
    cmap='RdBu_r',
    issym=True,
    show_colorbar=True,
    grid_lines=True,
    grid_labels=True
)

# Create plot
fig, ax, im = data.plotX.single_plot(config)

Multi-Panel Plotting

# Plot multiple time steps
config = marEx.PlotConfig(
    title='Temperature Evolution',
    var_units='°C',
    cmap='viridis'
)

# Create wrapped subplots
fig, axes = data.plotX.multi_plot(config, col='time', col_wrap=3)

Animation

# Create animation
config = marEx.PlotConfig(
    title='Temperature Animation',
    var_units='°C',
    cmap='RdBu_r'
)

# Generate animation
movie_path = data.plotX.animate(
    config,
    plot_dir='./animations',
    file_name='temperature_evolution'
)

Structured Grid Usage

Regular Lat/Lon Grids

For structured grids (typical climate model output):

# Load gridded data
sst = xr.open_dataset('sst_regular.nc').sst

# Configure for geographic plotting
config = marEx.PlotConfig(
    title='Global Sea Surface Temperature',
    var_units='°C',
    cmap='coolwarm',
    show_colorbar=True,
    grid_lines=True,
    grid_labels=True
)

# Plot will automatically use GriddedPlotter
fig, ax, im = sst.plotX.single_plot(config)

Custom Dimension Names

# For data with non-standard coordinate names
config = marEx.PlotConfig(
    title='Temperature',
    var_units='°C',
    # Specify custom dimension mapping
    dimensions={'time': 'time', 'y': 'latitude', 'x': 'longitude'},
    coordinates={'time': 'time', 'y': 'latitude', 'x': 'longitude'}
)

fig, ax, im = data.plotX.single_plot(config)

Unstructured Grid Usage

Ocean Model Grids

For unstructured grids (e.g., FESOM, ICON-O):

# First specify grid information globally
marEx.specify_grid(
    grid_type='unstructured',
    fpath_tgrid='grid_info.nc',
    fpath_ckdtree='./ckdtree_indices/'
)

# Load unstructured data
sst = xr.open_dataset('sst_unstructured.nc').sst

# Configure plot
config = marEx.PlotConfig(
    title='Ocean Model SST',
    var_units='°C',
    cmap='thermal',
    show_colorbar=True
)

# Plot will automatically use UnstructuredPlotter
fig, ax, im = sst.plotX.single_plot(config)

Triangulation-Based Plotting

# Use triangulation file for native mesh plotting
marEx.specify_grid(
    grid_type='unstructured',
    fpath_tgrid='triangulation.nc'
)

config = marEx.PlotConfig(
    title='Native Mesh Visualization',
    var_units='Temperature (°C)',
    cmap='plasma'
)

fig, ax, im = data.plotX.single_plot(config)

Event ID Plotting

Special Configuration for Event IDs

# For plotting tracked event IDs
config = marEx.PlotConfig(
    title='Marine Heatwave Events',
    plot_IDs=True,  # Special handling for event IDs
    cmap='tab20'    # Discrete colormap for IDs
)

fig, ax, im = event_ids.plotX.single_plot(config)

Color Scaling Options

Percentile-Based Scaling

config = marEx.PlotConfig(
    title='Temperature Anomalies',
    var_units='°C',
    cmap='RdBu_r',
    cperc=[5, 95],  # Use 5th and 95th percentiles
    extend='both'
)

Symmetric Scaling

config = marEx.PlotConfig(
    title='Temperature Anomalies',
    var_units='°C',
    cmap='RdBu_r',
    issym=True,     # Symmetric around zero
    extend='both'
)

Manual Color Limits

config = marEx.PlotConfig(
    title='Temperature',
    var_units='°C',
    cmap='viridis',
    clim=(-2, 5),   # Manual color limits
    extend='both'
)

Error Handling

The plotting system provides comprehensive error handling:

try:
    fig, ax, im = data.plotX.single_plot(config)
except marEx.VisualisationError as e:
    print(f"Plotting error: {e}")
    print(f"Suggestions: {e.suggestions}")
except marEx.DependencyError as e:
    print(f"Missing dependency: {e}")

Integration with Matplotlib

Direct Matplotlib Integration

import matplotlib.pyplot as plt

# Create custom figure
fig, ax = plt.subplots(figsize=(12, 8))

# Use existing axes
config = marEx.PlotConfig(title='Custom Plot')
fig, ax, im = data.plotX.single_plot(config, ax=ax)

# Add custom elements
ax.set_title('Custom Title', fontsize=14)
plt.tight_layout()

See Also

  • marEx.plotX.base - Base plotting functionality

  • marEx.plotX.gridded - Structured grid plotting

  • marEx.plotX.unstructured - Unstructured grid plotting

  • marEx.detect - Data preprocessing

  • marEx.track - Event tracking