sidescanpy.viz.waterfall#
Waterfall plotting for SideScan sonar.
Plots a port+starboard combined waterfall image with configurable x-axis (sample, ground_range, across_track, slant_range) and y-axis (ping, time, along_track) modes. Returns the matplotlib Axes for further customization.
2026 rshomberg@uri.edu
Contents
Plot a port+starboard combined waterfall. |
|
Pick the waterfall x/y axis mode for a given correction's step set. |
|
Compressed, whole-survey waterfall overview. |
- sidescanpy.viz.waterfall.plot_waterfall(ds, *, start=0, stop=None, x_axis='sample', y_axis='ping', ping_offset=0, cmap='copper', vmin=None, vmax=None, vmin_pct=1.0, vmax_pct=99.0, gamma=1.0, show_colorbar=False, ax=None, title=None, value_var='backscatter_intensity')#
Plot a port+starboard combined waterfall.
- Parameters:
- dsxr.Dataset
Validated sidescan dataset.
- value_varstr, default “backscatter_intensity”
Which backscatter variable to plot – the TVG-corrected default, or any other per-sample variable (e.g. one holding
sidescanpy.processing.uncorrected_backscatter(ds)for an uncorrected view of a corrected dataset).- startint, default 0
First ping index to include.
- stopint, optional
One past last ping index. Defaults to all pings.
- x_axis{“sample”, “ground_range”, “across_track”, “slant_range”}
How to interpret the x-axis.
"sample": sample number, port mirrored (-N to +N). Always works."ground_range": across-bottom distance, signed by channel (port = negative). Requiresground_range_mfromcompute_geometric_ranges."across_track": signed across-track in platform frame (already negative for port). Requiresacross_track_m."slant_range": attitude-invariant time-of-flight range, signed by channel (port = negative) the same way as"ground_range". Unlike ground range, always finite (never NaN in the water column) — useful when the water column itself needs to stay visible/maskable by a caller rather than being NaN’d out by the range variable’s own geometry. Requiresslant_range_m.
- y_axis{“ping”, “time”, “along_track”}
How to interpret the y-axis.
"ping": ping number."time": ping timestamp."along_track": cumulative platform distance from first ping. Computed viapyproj.Geod.invfrom per-ping latitude/ longitude.
- ping_offsetint, default 0
Added to
y_axis="ping"values (and to the title’s ping range). Use whendsis itself an already-extracted window of a larger survey (e.g. one segment of a multi-file concatenated channel) so the y-axis reports the segment’s true position in the full survey instead of 0-based local indices. Ignored fory_axis="time"/"along_track"— those are derived fromds’s own per-ping fields and need no external offset.- cmapstr or Colormap, default “copper”
Matplotlib colormap.
- vmin, vmaxfloat, optional
Color scale bounds. If not given, computed from percentiles (
vmin_pctandvmax_pct) of the finite values that are drawn: samples without an x coordinate (such as the water column in ground-range modes) are left out.- vmin_pct, vmax_pctfloat, default 1.0 and 99.0
Percentiles for auto color scaling. Ignored if
vminorvmaxis given.- gammafloat, default 1.0
Display-only power-law contrast curve, applied via
matplotlib.colors.PowerNorm(gamma, vmin, vmax)instead of a plain linearNormalize. The plotted array itself is never modified — only the value-to-color mapping is warped — so the backscatter stays real dB and (ifshow_colorbar=True) the colorbar keeps honest dB tick values, just non-uniformly spaced.gamma=1.0(default) is a linear scale, identical to this function’s behavior before this parameter existed.- show_colorbarbool, default False
If True, add a colorbar labeled “Backscatter (dB)”.
- axmatplotlib.axes.Axes, optional
Axes to plot on. If not given, creates a new figure with a single Axes.
- titlestr, optional
Plot title. Default: ping range and processing level.
- Returns:
- Axes
The matplotlib Axes containing the plot.
- Raises:
- ValueError
If a required variable is missing for the chosen axis mode.
- sidescanpy.viz.waterfall.resolve_waterfall_axes(steps, cli_x_axis, cli_y_axis)#
Pick the waterfall x/y axis mode for a given correction’s step set.
Corrections that include the “geometric” step always render in real-world distance (across_track x meters-in / along_track meters) rather than the caller’s chosen x/y axis — otherwise the geometric correction has no visible effect (sample-index and raw ping-count axes look identical whether or not ground/across-track ranges were computed, since only the color values change from TVG, not the pixel geometry). The caller’s axes remain in effect for corrections without “geometric” (raw, radiometric), where sample/ping/time are the only meaningful choices anyway.
- sidescanpy.viz.waterfall.plot_survey_overview(ds, *, ping_stride=20, break_ping_indices=None, x_axis='sample', cmap='copper', vmin=None, vmax=None, vmin_pct=1.0, vmax_pct=99.0, gamma=1.0, show_colorbar=False, ax=None, title=None, value_var='backscatter_intensity')#
Compressed, whole-survey waterfall overview.
Strides the ping axis by
ping_stridebefore rendering (viaplot_waterfall), so a very long survey renders as one reasonably-sized image instead of one row of pixels per ping. Optionally draws a horizontal marker line + ping-number label at each index inbreak_ping_indices— useful for e.g. file boundaries in a multi-file concatenated survey. Nothing inSideScanSurvey/.ss.h5currently records per-ping source-file identity, so if you need break markers, compute the boundary ping indices yourself (e.g. while concatenating per-file datasets) and pass them in here.- Parameters:
- dsxr.Dataset
Validated sidescan dataset (typically a whole survey/channel, not a pre-sliced segment).
- ping_strideint, default 20
Vertical compression factor — every
ping_stride-th ping is kept. Higher = more compressed. Must be >= 1.- break_ping_indiceslist[int], optional
Ping indices (in
ds’s own, un-strided index space) at which to draw a break marker — e.g. where one source file ends and the next begins in a concatenated survey.- x_axis, cmap, vmin, vmax, vmin_pct, vmax_pct, gamma, show_colorbar, ax, title
Same meaning as in
plot_waterfall.titledefaults to a summary of the total ping count and compression factor.
- Returns:
- Axes
The matplotlib Axes containing the plot. The y-axis is labeled with true ping numbers (not the strided/local index), even though the underlying mesh is built from the strided data.
- Raises:
- ValueError
If
ping_strideis not a positive integer, or (viaplot_waterfall) if a required variable is missing for the chosenx_axismode.