Skip to content

Directional Statistics

Apply one or more stat functions over equal-width directional sectors.


statdir

Bins the dataset by direction, applies each listed function to each sector, and concatenates the results along a new direction dimension.

Parameter Type Default Description
funcs list[str] — Names of registered stat functions to apply per sector (e.g. [mean, max]).
dir_var str "dpm" Variable name used for directional binning. Must be in the dataset.
nsector int 4 Number of equally-spaced sectors. 8 → 45° sectors, 16 → 22.5°, etc.

Additional keyword arguments (e.g. group) are forwarded to each stat function. They are shared by every function in funcs, so statistics needing different arguments have to be requested in separate calls. When group is set, every function in funcs must support grouping.

The stat names its outputs {variable}_{func} — a single function is suffixed too, so a name never depends on how many functions were asked for — and the pipeline then appends the group (when set) and _direc. A funcs: [mean, max] call over hs writes hs_mean_direc and hs_max_direc, exactly the names the equivalent nsector calls produce. Every variable gains a direction coordinate holding the sector-centre values (0°, 45°, …).

The directional variable must be present in the data the call sees, so include it in data_vars when that list is explicit. It is itself reduced by each function, giving dpm_mean_direc and so on.

- func: statdir
  dim: time
  data_vars: [hs, tp, dpm]
  dir_var: dpm
  nsector: 8
  funcs: [mean, max]

How sectors are defined

For nsector: N the sector width is 360 / N degrees. Sectors are centred on:

0°, 360/N°, 2×360/N°, …

Each sector is a half-open interval [centre − width/2, centre + width/2). The wrap-around sector (centred on 0°) correctly handles the 0°/360° boundary.

Data points outside a sector are set to NaN before the stat function is called, so all registered functions work transparently without modification.


Difference from nsector on individual calls

Setting nsector on a regular call (e.g. func: mean, nsector: 8) is handled at the pipeline level and applies a single function. statdir lets you apply multiple functions in one pass while keeping the same directional binning, which is more efficient when you need several statistics per sector.

The two routes are otherwise interchangeable: they bin the data identically and write identical variable names, so statdir adds no capability of its own — it exists to share one masking of the data and one pass over it between several statistics. Prefer nsector on individual calls unless that matters, or when the statistics need different keyword arguments (which statdir cannot express, since its extra arguments go to every function).

# Equivalent to two separate calls with nsector, but done in one pass:
- func: statdir
  dim: time
  data_vars: [hs, dpm]
  nsector: 16
  funcs: [mean, max]

API reference

gridstats.ops.directional.statdir(data: xr.Dataset, *, funcs: list[str], dir_var: str = 'dpm', nsector: int = 4, dim: str = 'time', group: str | None = None, **kwargs: Any) -> xr.Dataset

Apply multiple stat functions over directional sectors.

Bins the dataset by nsector equal directional sectors, applies each function in funcs to each sector, then concatenates results along a new 'direction' dimension.

Each delegated statistic returns its result under the name of the variable it was computed from, so the outputs of two functions would collide on merge. They are therefore suffixed with the function that produced them: funcs: [mean, max] over hs yields hs_mean and hs_max. The suffix is applied for a single function too, so a name never depends on how many functions were requested.

Parameters:

Name Type Description Default
data Dataset

Input dataset. Must contain dir_var — when the call selects data_vars explicitly, the directional variable has to be among them.

required
funcs list[str]

Names of registered stat functions to apply per sector.

required
dir_var str

Name of the directional variable used for binning.

'dpm'
nsector int

Number of equally-spaced directional sectors (default 4).

4
dim str

Time dimension name.

'time'
group str | None

Time component for a grouped climatology ('month', 'season', 'year'), passed through to every delegated stat. All of them must support grouping.

None
**kwargs Any

Forwarded to each stat function. They are shared by every function in funcs; per-function keyword arguments are not supported.

{}

Returns:

Type Description
Dataset

Dataset with one variable per {variable}_{func} combination, each

Dataset

gaining a 'direction' dimension holding the sector-centre values.

Raises:

Type Description
ValueError

If funcs is empty, if dir_var is missing from the dataset, or if group is set and one of funcs cannot honour it.

Note

This stat adds no capability that the pipeline's own nsector field does not already provide: func: mean with nsector: 8 produces exactly the same variable, under exactly the same output name, as func: statdir with funcs: [mean] and nsector: 8. Its reason to exist is efficiency — several statistics share one directional masking of the data and one pass over it, instead of one full pass per call. Prefer nsector on individual calls unless that matters, or when the statistics need different keyword arguments.


Per-cell modal (most frequent) direction from a weighted circular histogram. Uses a histogram-based mode rather than a vector mean, making it robust to bimodal and anti-parallel direction distributions (e.g. monsoon reversals where the arithmetic mean of 90° and 270° is meaningless).

All direction variables in data_vars are processed; the optional weight_var is excluded from output but used to weight the histogram.

Parameter Type Default Description
weight_var str | None None Variable name for histogram weights. None = unweighted frequency.
bin_width_deg float 10.0 Histogram bin width (degrees). Must divide 360 evenly.
smooth bool True Apply 3-bin circular moving average before taking the mode, stabilising against single-bin noise.
- func: modal_direction
  dim: time
  data_vars: [dpm, dp_sea, dp_sw1]
  weight_var: hs           # weight by wave energy
  bin_width_deg: 10.0
  smooth: true

With monthly grouping:

- func: modal_direction
  dim: time
  group: month
  data_vars: [dpm]
  weight_var: hs

Note

apply_ufunc with allow_rechunk=True handles the single-chunk requirement along dim automatically in the dask graph — no manual rechunking needed before calling this stat.

API reference

gridstats.ops.directional.modal_direction(data: xr.Dataset, *, dim: str = 'time', group: str | None = None, weight_var: str | None = None, bin_width_deg: float = 10.0, smooth: bool = True, **kwargs: Any) -> xr.Dataset

Per-cell modal (most frequent) direction from a weighted circular histogram.

Uses a histogram-based mode rather than a vector mean, so it is robust to bimodal and anti-parallel direction distributions (e.g. monsoon reversals where the arithmetic mean of 90° and 270° is meaningless).

Parameters:

Name Type Description Default
data Dataset

Input dataset. Direction variables must be in degrees in [0, 360).

required
dim str

Dimension to reduce along (default 'time').

'time'
group str | None

Time component for grouped climatology: 'month', 'season', or 'year'. When set, the output gains a dimension named after the group (e.g. a 'month' dimension with values 1–12).

None
weight_var str | None

Name of a variable in data to use as histogram weights. Typical choices: 'hs' for occurrence, 'hs'**2 for energy, 'hs'**2 * 'te' for energy flux. When None each sample contributes equally (unweighted frequency histogram).

None
bin_width_deg float

Histogram bin width in degrees. Must divide 360 evenly. 10° (36 bins) is a good default; use 5° for sharper modes on long records.

10.0
smooth bool

If True (default), apply a 3-bin circular moving average to the histogram before taking the argmax, stabilising the mode against single-bin noise.

True
**kwargs Any

Accepted but not forwarded (pipeline compatibility).

{}

Returns:

Type Description
Dataset

Dataset with one variable per direction variable in data (excluding

Dataset

weight_var). Each variable holds the centre of the dominant histogram

Dataset

bin at every grid cell. Gains a group dimension when group is set.

Note

apply_ufunc with allow_rechunk=True handles the single-chunk requirement along dim automatically in the dask graph, so manual rechunking is not needed before calling this stat.