Skip to content

radrs.viz

Raystack plots: PPI sweeps, unfolded waterfalls, and 3-D geographic point clouds.

Needs the viz extra: uv add 'radrs[viz]'.

VcpInfo dataclass

One volume coverage pattern in a raystack, for selector controls.

SweepInfo dataclass

One sweep within a VCP, for selector controls.

plot_sweep

plot_sweep(
    rs_dt: DataTree,
    sweep_num: int,
    moment_name: str = "DBZH",
    vcp_num: int = 0,
    plot_kwargs: Mapping[str, Any] = {},
)

Plot one sweep as a PPI. See :func:plot_sweeps for the parameters.

plot_sweeps

plot_sweeps(
    rs_dt: DataTree,
    sweep_nums: Sequence[int],
    moment_name: str = "DBZH",
    vcp_num: int = 0,
    *,
    cmaps: Sequence[Any] | None = None,
    alpha: float = 0.6,
    figsize: tuple[float, float] = (9.0, 8.0),
    plot_kwargs: Mapping[str, Any] = {},
)

Plot one or more sweeps as overlaid PPIs, in km from the radar.

Sweeps are drawn in the order given, each over the last at alpha transparency (the first is opaque) and each in its own colormap: yellow to green, then blue to purple, then orange to red, then matplotlib defaults. NaN gates are transparent, so lower sweeps show through the gaps.

Parameters:

Name Type Description Default
rs_dt DataTree

Raystack tree, from open_datatree or BatchedRaystack.finalize_to_rs_dt.

required
sweep_nums sequence of int

sweep_number values, as reported by :func:sweep_infos.

required
moment_name str

Moment variable in returns.

"DBZH"
vcp_num int

Index of the VCP in time order; 0 is the first volume in the raystack.

0
cmaps sequence

Per-sweep colormaps (names or Colormap) replacing the defaults.

None
alpha float

Transparency of every sweep after the first.

0.6
plot_kwargs mapping

Extra arguments for Axes.pcolormesh. vmin/vmax here pin the color scale across all sweeps instead of autoscaling each one.

{}

Returns:

Type Description
(Figure, Axes)

plot_waterfall

plot_waterfall(
    rs_dt: DataTree,
    moment_name: str = "DBZH",
    *,
    row_offset: int = 0,
    row_count: int | None = None,
    max_rows: int = 1500,
    max_cols: int = 1200,
    reduce: str = "max",
    figsize: tuple[float, float] = (12.0, 9.0),
    plot_kwargs: Mapping[str, Any] = {},
)

Plot every return against true range, stacked in time.

One image row per return row, unfolded onto an absolute range axis, so each radial's folds read as a staircase and dotted vertical lines mark where each fold window begins. Black is range no fold ever covered; white is a gate that was sampled and came back NaN.

Two strips run down the left, aligned with the rows: VCP number in tab20b (ruled at each volume boundary, since a batch from one site usually repeats a single VCP number) and sweep number in tab20c. Red ticks inside the axis mark each distinct return time, exposing radial boundaries and sparse folds.

Parameters:

Name Type Description Default
rs_dt DataTree

Raystack tree.

required
moment_name str

Moment variable in returns.

"DBZH"
row_offset int

Window of return rows to draw. Zoom in far enough and the red radial ticks stop merging, which is the only way to read fold structure on a raystack of more than a couple thousand radials.

0
row_count int

Window of return rows to draw. Zoom in far enough and the red radial ticks stop merging, which is the only way to read fold structure on a raystack of more than a couple thousand radials.

0
max_rows int

Rows and range bins are block-reduced to fit these caps; a raystack has far more returns than a figure has pixels.

1500
max_cols int

Rows and range bins are block-reduced to fit these caps; a raystack has far more returns than a figure has pixels.

1500
reduce ('max', 'mean')

Reducer for that block-reduction. max keeps echoes crisp; mean suits signed moments like VRADH.

"max"
plot_kwargs mapping

Extra arguments for Axes.imshow (vmin, vmax, cmap, ...).

{}

Returns:

Type Description
(Figure, Axes)

The axes is the returns panel, not the side strips.

plot_geo

plot_geo(
    rs_dt: DataTree,
    moment_name: str = "DBZH",
    *,
    vcp_num: int | None = None,
    min_value: float | None = None,
    max_points: int = 30000,
    point_size: float = 30.0,
    opacity: float = 0.85,
    pitch: float = 50.0,
    cmap: Any = None,
    map_style: str | None = None,
    plot_kwargs: Mapping[str, Any] = {},
)

Render finite gates as a 3-D point cloud on a real-world map.

Returns a pydeck.Deck, which marimo and Jupyter display directly. The view rotates, so the vertical structure of the volume is legible from the side; colors match :func:plot_sweep's default yellow-to-green.

Parameters:

Name Type Description Default
rs_dt DataTree

Raystack tree.

required
moment_name str

Moment variable in returns.

"DBZH"
vcp_num int

Index of the VCP in time order. Default plots every return in the raystack, geolocated against the first VCP's site.

None
min_value float

Drop gates below this value. Without it a volume of weak returns fogs the map, so set it (20 dBZ or so for DBZH).

None
max_points int

Cap on rendered gates, bounding notebook output size — deck.gl data travels as JSON, at roughly 90 bytes a point. Excess gates are dropped by strided subsampling.

30000
point_size float

Point radius in metres.

30
cmap str or Colormap

Replaces the default yellow-to-green ramp.

None
map_style str

pydeck basemap style. Defaults to Carto dark, which needs no API token.

None
plot_kwargs mapping

Extra arguments for pydeck.Deck.

{}

Returns:

Type Description
Deck

gate_positions

gate_positions(
    rs_dt: DataTree,
    moment_name: str = "DBZH",
    *,
    vcp_num: int | None = None,
    min_value: float | None = None,
    max_points: int = 30000,
) -> dict[str, ndarray]

Geolocate finite gates to longitude/latitude/altitude/value arrays.

Beam height uses the standard 4/3-earth-radius refraction model, so altitudes are above mean sea level rather than above the radar.

vcp_infos

vcp_infos(rs_dt: DataTree) -> list[VcpInfo]

Describe every VCP in the raystack, ordered in time.

sweep_infos

sweep_infos(
    rs_dt: DataTree, vcp_num: int = 0
) -> list[SweepInfo]

Describe the sweeps of one VCP, ordered by sweep number.

vcp_num indexes the VCPs in time order; 0 is the first volume.

available_moments

available_moments(
    rs_dt: DataTree, include_qc: bool = True
) -> list[str]

List the plottable moment variables present in returns.

value_bounds

value_bounds(values: ndarray) -> tuple[float, float]

Robust (vmin, vmax) for a moment, from its 2nd and 98th percentiles.