2.25.3.19. pycsamt.ai.processing.plot#

Visualisation helpers for pycsamt.ai.processing output.

QC (EMQCScorer)
  • plot_qc_scores() — per-station bar chart

  • plot_qc_heatmap() — station × freq. heat-map

  • plot_qc_feature_heatmap() — one panel per QC feature

  • plot_qc_score_distribution() — score histogram + KDE

  • plot_qc_score_spread() — violin / box / strip

  • plot_qc_summary() — 3-panel summary figure

Denoising (EMDenoiser)
  • plot_denoise_spectra() — before/after spectra, per site

  • plot_denoise_noise_reduction() — per-station roughness reduction

  • plot_denoise_summary() — combined summary figure

Anomaly detection (AnomalyDetector)
  • plot_anomaly_scores() — per-station bar chart

  • plot_anomaly_score_distribution() — score histogram + KDE

  • plot_anomaly_summary() — 2-panel summary figure

Dimensionality (DimensionalityClassifier)
  • plot_dimensionality_map() — station × freq. class map

  • plot_predicted_strike_rose() — 2-D strike rose diagram

  • plot_dimensionality_summary() — 3-panel summary figure

Gap filling (EMImputer)
  • plot_imputer_gaps() — station × freq. missing-data map

  • plot_imputer_validation() — held-out true-vs-reconstructed scatter, faceted by component

  • plot_imputer_reconstruction() — per-site spectra, reconstructed cells highlighted

  • plot_imputer_summary() — 3-panel summary figure

Uncertainty calibration (UncertaintyCalibrator)
  • plot_uncertainty_map() — station × freq. fractional-error heat-map (log colour scale)

  • plot_uncertainty_validation() — held-out true-vs-calibrated scatter

  • plot_uncertainty_summary() — 4-panel summary figure

Distortion triage (DistortionTypeClassifier)
  • plot_distortion_map() — per-station regime bar chart

  • plot_distortion_feature_space() — feature scatter coloured by regime, with rule thresholds

  • plot_distortion_summary() — 4-panel summary figure

Time-series denoising (TimeSeriesDenoiser)
  • plot_ts_denoise_mmf_split() — raw + low-frequency envelope, high-frequency residual

  • plot_ts_denoise_segments() — residual with SVM-flagged noisy windows shaded

  • plot_ts_denoise_summary() — 3-panel before/after summary

Shared
  • plot_training_history() — train/val loss curve for any of the three network-based estimators above.

Functions

plot_anomaly_score_distribution(scores, *[, ...])

Anomaly-score histogram and optional KDE, mirroring plot_qc_score_distribution().

plot_anomaly_scores(scores, *[, ...])

Per-station anomaly-score bar chart, mirroring plot_qc_scores().

plot_anomaly_summary(scores, *[, ...])

Two-panel anomaly-detection summary: per-station bar chart and score distribution, sharing one resolved threshold.

plot_denoise_noise_reduction(X_raw, ...[, ...])

Per-station roughness reduction achieved by EMDenoiser.

plot_denoise_spectra(freq, X_raw, X_denoised, *)

Before/after spectra for EMDenoiser.

plot_denoise_summary(freq, X_raw, X_denoised, *)

Combined denoiser figure: before/after spectra, per-station roughness reduction, and (when available) the training curve.

plot_dimensionality_map(df, *[, dim_col, ...])

Station × frequency dimensionality-class heat-map.

plot_dimensionality_summary(df, *[, ...])

Three-panel dimensionality-classification summary.

plot_distortion_feature_space(table, *[, ...])

Two-feature scatter coloured by predicted distortion regime, for DistortionTypeClassifier.

plot_distortion_map(table, *[, ...])

Per-station distortion-regime bar chart, for DistortionTypeClassifier.

plot_distortion_summary(table, *[, history, ...])

Combined DistortionTypeClassifier figure: the per-station regime map, the feature-space scatter that explains it, class proportions, and (when available) the training curve.

plot_imputer_gaps(gap_table, *[, ...])

Station x frequency map of genuinely missing cells for EMImputer.

plot_imputer_reconstruction(freq, X_raw, ...)

Per-station, per-channel spectra with reconstructed cells highlighted, for EMImputer.

plot_imputer_summary(gap_table, freq, X_raw, ...)

Combined EMImputer figure: the missing-data map, reconstruction detail for a handful of sites, and (when available) the training curve.

plot_imputer_validation(y_true, y_pred, *[, ...])

Predicted-vs-true scatter for a synthetic held-out-cell validation of EMImputer.

plot_predicted_strike_rose(strike_deg, *[, ...])

Rose diagram of predicted geoelectric strike directions.

plot_qc_feature_heatmap(df, *[, features, ...])

One panel per QC feature — station × frequency heat-maps.

plot_qc_heatmap(scores, *[, station_labels, ...])

Station × frequency QC-score heat-map.

plot_qc_score_distribution(scores, *[, ...])

Score histogram and optional KDE per profile.

plot_qc_score_spread(scores, *[, ...])

Per-profile score spread: violin, box, or jitter-strip plot.

plot_qc_scores(scores, *[, station_labels, ...])

Per-station QC-score bar chart, optionally grouped by profile.

plot_qc_summary(scores, *[, station_labels, ...])

Three-panel QC summary figure.

plot_training_history(history, *[, ...])

Train/validation loss curve for a pycsamt.ai.processing estimator.

plot_ts_denoise_mmf_split(t, x, low, high, *)

Mathematical-morphological-filter (MMF) low/high split.

plot_ts_denoise_segments(t, high, diagnostics, *)

High-frequency residual with SVM window classification overlaid.

plot_ts_denoise_summary(t, x, denoised, ...)

Combined before/after summary for TimeSeriesDenoiser.

plot_uncertainty_map(table, *[, value_col, ...])

Station x frequency heat-map of a fractional-error column, for UncertaintyCalibrator.

plot_uncertainty_summary(table, y_true, ...)

Combined UncertaintyCalibrator figure: the calibrated-error map, a per-station original-vs.- calibrated comparison, the held-out validation scatter, and (when available) the training curve.

plot_uncertainty_validation(y_true, y_pred, *)

Predicted-vs-true scatter for UncertaintyCalibrator.

pycsamt.ai.processing.plot.plot_qc_scores(scores, *, station_labels=None, profile_colors=None, score_threshold=0.5, threshold_color='#c0392b', threshold_lw=1.4, threshold_ls='--', bad_zone_color='#fde8e8', bad_zone_alpha=0.3, bar_width=0.8, bar_alpha=0.88, show_scatter=True, show_profile_labels=True, profile_label_fontsize=8, separator_color='gray', separator_lw=0.7, separator_ls='--', show_zone_labels=True, zone_label_fontsize=8, tick_every='auto', tick_label_rotation=45.0, tick_fontsize=7, station_tick_config=None, xlabel='Station', ylabel='QC score', title='', ylim=None, show_grid=True, figsize=(10.0, 4.2), ax=None)[source]

Per-station QC-score bar chart, optionally grouped by profile.

Handles label overlap automatically: tick_every="auto" (the default) picks the smallest nice step (1 → 2 → 5 → 10 → 25 → …) so that station labels never overlap, regardless of how many stations are shown. Pass a StationTickConfig via station_tick_config for fine-grained reusable control.

Parameters:
  • scores (ndarray, dict, or DataFrame) –

    Quality scores. Accepted forms:

    • ndarray shape (n_st,) — single profile.

    • dict[str, ndarray] — one 1-D array per profile name.

    • pandas.DataFrame from EMQCScorer.score_table() — requires a score column; optional station, freq, profile columns are used when present.

  • station_labels (list of str or None) – X-axis tick labels. Inferred from the station column when scores is a DataFrame. Defaults to integer index strings.

  • profile_colors (dict, list, or None) – {profile_name: color} mapping, ordered list, or None for the built-in colour cycle.

  • score_threshold (float, default 0.5) – Threshold line and rejection-zone boundary.

  • threshold_color (str, float, str)

  • threshold_lw (str, float, str)

  • threshold_ls (str, float, str)

  • bad_zone_color (str, float)

  • bad_zone_alpha (str, float)

  • bar_width (float, default 0.80)

  • bar_alpha (float, default 0.88)

  • show_scatter (bool, default True) – When scores is a DataFrame with a freq column, draw semi-transparent per-frequency score dots behind each bar.

  • show_profile_labels (bool, default True)

  • profile_label_fontsize (int, default 8)

  • separator_color (str, float, str)

  • separator_lw (str, float, str)

  • separator_ls (str, float, str)

  • show_zone_labels (bool, default True) – Add “Good ▶” / “◀ Review” margin annotations.

  • zone_label_fontsize (int, default 8)

  • tick_every (int or "auto", default "auto") – Station tick step. "auto" computes the step from the figure width and label length so labels never overlap. Pass an integer to force a fixed step, e.g. tick_every=5 shows every 5th label.

  • tick_label_rotation (float, default 45.0)

  • tick_fontsize (int, default 7)

  • station_tick_config (StationTickConfig or None) – If provided, overrides tick_every, tick_label_rotation, and tick_fontsize entirely.

  • xlabel (str)

  • ylabel (str)

  • title (str)

  • ylim ((ymin, ymax) or None)

  • show_grid (bool, default True)

  • figsize ((w, h), default (10.0, 4.2))

  • ax (Axes or None)

Returns:

ax

Return type:

matplotlib.axes.Axes

Examples

>>> from pycsamt.ai.processing.plot import plot_qc_scores
>>> plot_qc_scores({"L18": sc_18, "L22": sc_22}, tick_every=5)
>>> from pycsamt.ai.plot import StationTickConfig
>>> cfg = StationTickConfig(every=10, rotation=30, fontsize=8)
>>> plot_qc_scores(scores_dict, station_tick_config=cfg)
pycsamt.ai.processing.plot.plot_qc_heatmap(scores, *, station_labels=None, score_threshold=0.5, cmap='RdYlGn', vmin=0.0, vmax=1.0, period_up=True, show_threshold_contour=True, contour_color='white', contour_lw=0.8, n_yticks=7, colorbar_label='QC score', xlabel='Station', ylabel='Period (s)', title='', station_markers=True, tick_every='auto', tick_label_rotation=45.0, tick_fontsize=7, station_tick_config=None, figsize=(10.0, 5.2), ax=None)[source]

Station × frequency QC-score heat-map.

Parameters:
  • scores (DataFrame) – Must contain station, freq, and score columns (output of score_table()).

  • station_labels (list of str or None)

  • score_threshold (float, default 0.5)

  • cmap (str, default "RdYlGn")

  • vmin (float)

  • vmax (float)

  • period_up (bool, default True)

  • show_threshold_contour (bool, default True)

  • contour_color (str, float)

  • contour_lw (str, float)

  • n_yticks (int, default 7)

  • colorbar_label (str)

  • xlabel (str)

  • ylabel (str)

  • title (str)

  • station_markers (bool, default True) – Draw the station axis at the top with pyCSAMT’s shared downward-triangle convention ( PYCSAMT_STATION_RENDERING), the same rendering used throughout the rest of the package for period/station sections. Set to False to fall back to a plain bottom axis controlled by tick_every / tick_label_rotation / tick_fontsize / station_tick_config instead.

  • tick_every (int or "auto") – Only used when station_markers=False.

  • tick_label_rotation (float, default 45.0) – Only used when station_markers=False.

  • tick_fontsize (int, default 7) – Only used when station_markers=False.

  • station_tick_config (StationTickConfig or None) – Only used when station_markers=False.

  • figsize ((w, h))

  • ax (Axes or None)

Returns:

ax

Return type:

matplotlib.axes.Axes

pycsamt.ai.processing.plot.plot_qc_feature_heatmap(df, *, features=None, station_labels=None, cmaps=None, period_up=True, n_yticks=5, station_markers=True, tick_every='auto', tick_label_rotation=45.0, tick_fontsize=6, station_tick_config=None, clim_pct=(2.0, 98.0), title='', figsize=None)[source]

One panel per QC feature — station × frequency heat-maps.

Parameters:
  • df (DataFrame) – Output of EMQCScorer.score_table(). Must contain station, freq, and the feature columns.

  • features (list of str or None) – Feature columns to plot. Defaults to all five QC features.

  • station_labels (list of str or None)

  • cmaps (dict or None) – {feature: cmap_name} overrides.

  • period_up (bool, default True)

  • n_yticks (int, default 5)

  • station_markers (bool, default True) – Draw the station axis once, above the top panel, using pyCSAMT’s shared downward-triangle convention (see plot_qc_heatmap()). Set to False for a plain bottom axis on the last panel, controlled by tick_every / tick_label_rotation / tick_fontsize / station_tick_config.

  • tick_every (tick control) – Only used when station_markers=False.

  • tick_label_rotation (tick control) – Only used when station_markers=False.

  • tick_fontsize (tick control) – Only used when station_markers=False.

  • station_tick_config (StationTickConfig or None) – Only used when station_markers=False.

  • clim_pct ((lo, hi), default (2.0, 98.0))

  • title (str)

  • figsize ((w, h) or None)

Returns:

fig

Return type:

matplotlib.figure.Figure

pycsamt.ai.processing.plot.plot_qc_score_distribution(scores, *, station_labels=None, profile_colors=None, score_threshold=0.5, n_bins=20, show_kde=True, kde_bw=None, fill_alpha=0.35, line_lw=1.8, threshold_color='#c0392b', threshold_lw=1.3, threshold_ls='--', xlabel='QC score', ylabel='Density', title='', show_legend=True, figsize=(6.0, 4.0), ax=None)[source]

Score histogram and optional KDE per profile.

Each profile’s scores are shown as a semi-transparent histogram with an overlaid KDE curve. The review threshold is marked as a vertical line. Suitable as a standalone figure or embedded in a summary panel.

Parameters:
  • scores (ndarray, dict, or DataFrame) – Same flexible input as plot_qc_scores().

  • station_labels (list of str or None)

  • profile_colors (dict, list, or None)

  • score_threshold (float, default 0.5)

  • n_bins (int, default 20)

  • show_kde (bool, default True) – Overlay a KDE curve on top of each histogram.

  • kde_bw (float, str, or None) – KDE bandwidth passed to scipy.stats.gaussian_kde. None → Scott’s rule.

  • fill_alpha (float, default 0.35)

  • line_lw (float, default 1.8)

  • threshold_color (str, float, str)

  • threshold_lw (str, float, str)

  • threshold_ls (str, float, str)

  • xlabel (str)

  • ylabel (str)

  • title (str)

  • show_legend (bool, default True)

  • figsize ((w, h), default (6.0, 4.0))

  • ax (Axes or None)

Returns:

ax

Return type:

matplotlib.axes.Axes

pycsamt.ai.processing.plot.plot_qc_score_spread(scores, *, station_labels=None, profile_colors=None, score_threshold=0.5, kind='violin', show_scatter=True, scatter_alpha=0.25, scatter_size=5.0, jitter=0.08, violin_alpha=0.7, threshold_color='#c0392b', threshold_lw=1.3, threshold_ls='--', ylabel='QC score', title='', show_legend=False, figsize=(6.0, 4.0), ax=None)[source]

Per-profile score spread: violin, box, or jitter-strip plot.

Parameters:
  • scores (ndarray, dict, or DataFrame) – Same flexible input as plot_qc_scores().

  • station_labels (list of str or None)

  • profile_colors (dict, list, or None)

  • score_threshold (float, default 0.5)

  • kind ("violin" | "box" | "strip", default "violin") – Plot style. "strip" shows only jittered scatter dots.

  • show_scatter (bool, default True) – Overlay jittered scatter dots (ignored when kind is "strip").

  • scatter_alpha (float, default 0.25)

  • scatter_size (float, default 5.0)

  • jitter (float, default 0.08) – Maximum horizontal jitter width.

  • violin_alpha (float, default 0.70)

  • threshold_color (str, float, str)

  • threshold_lw (str, float, str)

  • threshold_ls (str, float, str)

  • ylabel (str)

  • title (str)

  • show_legend (bool, default False)

  • figsize ((w, h), default (6.0, 4.0))

  • ax (Axes or None)

Returns:

ax

Return type:

matplotlib.axes.Axes

pycsamt.ai.processing.plot.plot_qc_summary(scores, *, station_labels=None, profile_colors=None, score_threshold=0.5, show_scatter=True, n_bins=20, show_kde=True, kde_bw=None, spread_kind='violin', tick_every='auto', tick_label_rotation=45.0, tick_fontsize=7, station_tick_config=None, suptitle='', figsize=(13.0, 9.5))[source]

Three-panel QC summary figure.

Layout:

┌────────────────────────────────┐
│  (a) Per-station bar chart     │  full width
├──────────────────┬─────────────┤
│  (b) Score dist  │  (c) Spread │
│  histogram + KDE │  per profile│
└──────────────────┴─────────────┘

Panels (b) and (c) are produced by plot_qc_score_distribution() and plot_qc_score_spread() respectively, so they can also be used as standalone figures.

Parameters:
  • scores (ndarray, dict, or DataFrame) – Same flexible input as plot_qc_scores().

  • station_labels (list of str or None)

  • profile_colors (dict, list, or None)

  • score_threshold (float, default 0.5)

  • show_scatter (bool, default True)

  • n_bins (int, default 20)

  • show_kde (bool, default True)

  • kde_bw (float, str, or None)

  • spread_kind ("violin" | "box" | "strip")

  • tick_every (int or "auto")

  • tick_label_rotation (float, default 45.0)

  • tick_fontsize (int, default 7)

  • station_tick_config (StationTickConfig or None)

  • suptitle (str)

  • figsize ((w, h), default (13.0, 9.5))

Returns:

fig

Return type:

matplotlib.figure.Figure

pycsamt.ai.processing.plot.plot_denoise_spectra(freq, X_raw, X_denoised, *, station_labels=None, component_labels=None, sites=None, n_show=4, raw_color='#7f7f7f', denoised_color='#d62728', raw_alpha=0.75, log_freq=True, sharey='row', suptitle='', figsize=None)[source]

Before/after spectra for EMDenoiser.

One column per selected site, one row per feature component, following the (n_sites, n_components, n_freqs) array convention used by prepare_z_features().

Parameters:
  • freq (ndarray, shape (n_freqs,)) – Frequency grid in Hz shared by all sites (the freq_ref grid from prepare_z_features()).

  • X_raw (ndarray, shape (n_sites, n_components, n_freqs)) – Input and transform() output.

  • X_denoised (ndarray, shape (n_sites, n_components, n_freqs)) – Input and transform() output.

  • station_labels (list of str or None) – One label per site. Defaults to site0, site1, ....

  • component_labels (list of str or None) – One label per row. Defaults to the standard [log|Zxy|, phi_xy, log|Zyx|, phi_yx] ordering (or its 8-component variant) used by prepare_z_features().

  • sites (list of int or None) – Explicit site indices to display. Overrides n_show when given.

  • n_show (int, default 4) – Number of sites to display when sites is None — the first n_show sites are used.

  • raw_color (str)

  • denoised_color (str)

  • raw_alpha (float, default 0.75)

  • log_freq (bool, default True)

  • sharey ("row" | "none", default "row") – Share the y-axis across sites within each component row so amplitudes are directly comparable.

  • suptitle (str)

  • figsize ((w, h) or None)

Returns:

fig

Return type:

matplotlib.figure.Figure

Examples

>>> from pycsamt.ai.processing.plot import plot_denoise_spectra
>>> plot_denoise_spectra(
...     freq, X_noisy, X_denoised, n_show=3,
... )
pycsamt.ai.processing.plot.plot_denoise_noise_reduction(X_raw, X_denoised, *, station_labels=None, aggregate='mean', bar_color='#2166ac', negative_color='#c0392b', tick_every='auto', tick_label_rotation=45.0, tick_fontsize=7, station_tick_config=None, xlabel='Station', ylabel='Roughness reduction (%)', title='', show_grid=True, figsize=(10.0, 4.0), ax=None)[source]

Per-station roughness reduction achieved by EMDenoiser.

“Roughness” is the mean absolute second difference along the frequency axis — large for jagged, noisy spectra and small for smooth ones. The plotted quantity is the percentage reduction in roughness from X_raw to X_denoised, aggregated over feature components with aggregate. Positive values mean the denoiser removed high-frequency scatter; values near zero or negative flag stations where denoising had little effect or over-smoothed genuine structure.

Parameters:
  • X_raw (ndarray, shape (n_sites, n_components, n_freqs))

  • X_denoised (ndarray, shape (n_sites, n_components, n_freqs))

  • station_labels (list of str or None)

  • aggregate ("mean" | "median", default "mean") – Reduction statistic across components.

  • bar_color (str) – Colour for stations with a positive (improved) reduction.

  • negative_color (str) – Colour for stations with zero or negative reduction.

  • tick_every (tick control)

  • tick_label_rotation (tick control)

  • tick_fontsize (tick control)

  • station_tick_config (StationTickConfig or None)

  • xlabel (str)

  • ylabel (str)

  • title (str)

  • show_grid (bool, default True)

  • figsize ((w, h), default (10.0, 4.0))

  • ax (Axes or None)

Returns:

ax

Return type:

matplotlib.axes.Axes

pycsamt.ai.processing.plot.plot_denoise_summary(freq, X_raw, X_denoised, *, history=None, station_labels=None, component_labels=None, n_show=3, suptitle='', figsize=(13.0, 10.0))[source]

Combined denoiser figure: before/after spectra, per-station roughness reduction, and (when available) the training curve.

Layout:

┌──────────────────────────────────────────┐
│  Before / after spectra, n_show sites     │
├───────────────────────┬──────────────────┤
│ Roughness reduction   │ Training history  │
│ per station           │ (if available)    │
└───────────────────────┴──────────────────┘
Parameters:
Returns:

fig

Return type:

matplotlib.figure.Figure

pycsamt.ai.processing.plot.plot_anomaly_scores(scores, *, station_labels=None, profile_colors=None, threshold=None, threshold_percentile=95.0, threshold_color='#c0392b', threshold_lw=1.4, threshold_ls='--', bad_zone_color='#fde8e8', bad_zone_alpha=0.3, bar_width=0.8, bar_alpha=0.88, show_profile_labels=True, profile_label_fontsize=8, separator_color='gray', separator_lw=0.7, separator_ls='--', show_zone_labels=True, zone_label_fontsize=8, tick_every='auto', tick_label_rotation=45.0, tick_fontsize=7, station_tick_config=None, xlabel='Station', ylabel='Anomaly score (reconstruction error)', title='', ylim=None, show_grid=True, figsize=(10.0, 4.2), ax=None)[source]

Per-station anomaly-score bar chart, mirroring plot_qc_scores().

Unlike QC scores, higher values are worse: the shaded rejection band and the “Anomalous” label sit above the threshold line rather than below it.

Parameters:
  • scores (ndarray, dict, or DataFrame) – Reconstruction-error scores from transform(). Same flexible input as plot_qc_scores(): a single 1-D array, {profile: array}, or a DataFrame with a score column.

  • station_labels (list of str or None)

  • profile_colors (dict, list, or None)

  • threshold (float or None) – Explicit anomaly threshold. When None, computed as the threshold_percentile-th percentile of the pooled scores. Pass AnomalyDetector.threshold_ directly to plot the fitted value.

  • threshold_percentile (float, default 95.0)

  • threshold_color (str, float, str)

  • threshold_lw (str, float, str)

  • threshold_ls (str, float, str)

  • bad_zone_color (str, float)

  • bad_zone_alpha (str, float)

  • bar_width (float)

  • bar_alpha (float)

  • show_profile_labels (bool, default True)

  • profile_label_fontsize (int, default 8)

  • separator_color (str, float, str)

  • separator_lw (str, float, str)

  • separator_ls (str, float, str)

  • show_zone_labels (bool, default True)

  • zone_label_fontsize (int, default 8)

  • tick_every (tick control)

  • tick_label_rotation (tick control)

  • tick_fontsize (tick control)

  • station_tick_config (StationTickConfig or None)

  • xlabel (str)

  • ylabel (str)

  • title (str)

  • ylim ((ymin, ymax) or None) – Defaults to (0, 1.15 * max(scores, threshold)).

  • show_grid (bool, default True)

  • figsize ((w, h), default (10.0, 4.2))

  • ax (Axes or None)

Returns:

ax

Return type:

matplotlib.axes.Axes

Examples

>>> from pycsamt.ai.processing.plot import plot_anomaly_scores
>>> plot_anomaly_scores(
...     scores, threshold=det.threshold_,
... )
pycsamt.ai.processing.plot.plot_anomaly_score_distribution(scores, *, station_labels=None, profile_colors=None, threshold=None, threshold_percentile=95.0, n_bins=20, show_kde=True, kde_bw=None, fill_alpha=0.35, line_lw=1.8, threshold_color='#c0392b', threshold_lw=1.3, threshold_ls='--', xlabel='Anomaly score', ylabel='Density', title='', show_legend=True, figsize=(6.0, 4.0), ax=None)[source]

Anomaly-score histogram and optional KDE, mirroring plot_qc_score_distribution().

The shaded rejection band and threshold line sit to the right of the threshold value (high score = anomalous) — the opposite convention from the QC-score version.

Parameters:
  • scores (ndarray, dict, or DataFrame)

  • station_labels (list of str or None)

  • profile_colors (dict, list, or None)

  • threshold (float or None) – See plot_anomaly_scores().

  • threshold_percentile (float, default 95.0)

  • n_bins (int, default 20)

  • show_kde (bool, default True)

  • kde_bw (float, str, or None)

  • fill_alpha (float, default 0.35)

  • line_lw (float, default 1.8)

  • threshold_color (str, float, str)

  • threshold_lw (str, float, str)

  • threshold_ls (str, float, str)

  • xlabel (str)

  • ylabel (str)

  • title (str)

  • show_legend (bool, default True)

  • figsize ((w, h), default (6.0, 4.0))

  • ax (Axes or None)

Returns:

ax

Return type:

matplotlib.axes.Axes

pycsamt.ai.processing.plot.plot_anomaly_summary(scores, *, station_labels=None, profile_colors=None, threshold=None, threshold_percentile=95.0, n_bins=20, show_kde=True, tick_every='auto', tick_label_rotation=45.0, tick_fontsize=7, station_tick_config=None, suptitle='', figsize=(13.0, 4.6))[source]

Two-panel anomaly-detection summary: per-station bar chart and score distribution, sharing one resolved threshold.

Parameters:
  • scores (ndarray, dict, or DataFrame)

  • station_labels (list of str or None)

  • profile_colors (dict, list, or None)

  • threshold (float or None)

  • threshold_percentile (float, default 95.0)

  • n_bins (int, default 20)

  • show_kde (bool, default True)

  • tick_every (tick control)

  • tick_label_rotation (tick control)

  • tick_fontsize (tick control)

  • station_tick_config (StationTickConfig or None)

  • suptitle (str)

  • figsize ((w, h), default (13.0, 4.6))

Returns:

fig

Return type:

matplotlib.figure.Figure

pycsamt.ai.processing.plot.plot_dimensionality_map(df, *, dim_col='dim', station_labels=None, class_colors=('#2ca02c', '#1f77b4', '#d62728'), class_labels=('1-D', '2-D', '3-D'), period_up=True, n_yticks=7, station_markers=True, tick_every='auto', tick_label_rotation=45.0, tick_fontsize=7, station_tick_config=None, xlabel='Station', ylabel='Period (s)', title='', figsize=(10.0, 5.2), ax=None)[source]

Station × frequency dimensionality-class heat-map.

Renders the categorical 1-D / 2-D / 3-D output of DimensionalityClassifier.predict_table the same way plot_qc_heatmap() renders continuous QC scores, with a discrete three-colour legend in place of a colourbar.

Parameters:
  • df (DataFrame) – Output of DimensionalityClassifier.predict_table(). Must contain station, freq, and dim_col.

  • dim_col (str, default "dim") – Column with integer class labels (0=1-D, 1=2-D, 2=3-D).

  • station_labels (list of str or None)

  • class_colors ((str, str, str))

  • class_labels ((str, str, str))

  • period_up (bool, default True)

  • n_yticks (int, default 7)

  • station_markers (bool, default True) – Draw the station axis at the top with pyCSAMT’s shared downward-triangle convention (see plot_qc_heatmap()). Set to False for a plain bottom axis controlled by tick_every / tick_label_rotation / tick_fontsize / station_tick_config.

  • tick_every (tick control) – Only used when station_markers=False.

  • tick_label_rotation (tick control) – Only used when station_markers=False.

  • tick_fontsize (tick control) – Only used when station_markers=False.

  • station_tick_config (StationTickConfig or None) – Only used when station_markers=False.

  • xlabel (str)

  • ylabel (str)

  • title (str)

  • figsize ((w, h), default (10.0, 5.2))

  • ax (Axes or None)

Returns:

ax

Return type:

matplotlib.axes.Axes

pycsamt.ai.processing.plot.plot_predicted_strike_rose(strike_deg, *, bins=18, fold_180=True, color='#1f77b4', edgecolor='white', alpha=0.85, show_mean=True, mean_color='#d62728', title='', figsize=(5.0, 5.0), ax=None)[source]

Rose diagram of predicted geoelectric strike directions.

Parameters:
  • strike_deg (array-like or DataFrame) – Strike angles in degrees, typically the strike column returned by DimensionalityClassifier.predict_table() (NaN for non-2-D observations). A DataFrame is expected to carry a strike column.

  • bins (int, default 18) – Number of angular bins spanning 0-360 degrees (10-degree bins by default).

  • fold_180 (bool, default True) – Strike has a 180-degree ambiguity (a line has no direction of travel). When True, every angle is plotted together with its 180-degree-rotated counterpart so the rose is symmetric — the standard convention for strike roses.

  • color (str, str, float)

  • edgecolor (str, str, float)

  • alpha (str, str, float)

  • show_mean (bool, default True) – Draw a radial line at the circular mean strike.

  • mean_color (str)

  • title (str)

  • figsize ((w, h), default (5.0, 5.0))

  • ax (polar Axes or None) – When given, must have been created with subplot_kw={"projection": "polar"}.

Returns:

ax

Return type:

matplotlib.axes.Axes (polar)

Examples

>>> from pycsamt.ai.processing.plot import plot_predicted_strike_rose
>>> plot_predicted_strike_rose(
...     table["strike"], title="L18 strike rose",
... )
pycsamt.ai.processing.plot.plot_dimensionality_summary(df, *, dim_col='dim', strike_col='strike', station_labels=None, class_colors=('#2ca02c', '#1f77b4', '#d62728'), class_labels=('1-D', '2-D', '3-D'), tick_every='auto', tick_label_rotation=45.0, tick_fontsize=7, station_tick_config=None, rose_bins=18, suptitle='', figsize=(13.0, 9.0))[source]

Three-panel dimensionality-classification summary.

Layout:

┌────────────────────────────────────┐
│  Station × frequency dim map        │  full width
├───────────────────┬────────────────┤
│ Class proportions  │ Strike rose    │
│                    │ (2-D sites)    │
└───────────────────┴────────────────┘
Parameters:
  • df (DataFrame) – Output of DimensionalityClassifier.predict_table().

  • dim_col (str)

  • strike_col (str)

  • station_labels (list of str or None)

  • class_colors ((str, str, str))

  • class_labels ((str, str, str))

  • tick_every (tick control)

  • tick_label_rotation (tick control)

  • tick_fontsize (tick control)

  • station_tick_config (StationTickConfig or None)

  • rose_bins (int, default 18)

  • suptitle (str)

  • figsize ((w, h), default (13.0, 9.0))

Returns:

fig

Return type:

matplotlib.figure.Figure

pycsamt.ai.processing.plot.plot_imputer_gaps(gap_table, *, status_col='missing', station_labels=None, observed_color='#2166ac', missing_color='#d62728', period_up=True, colorbar_label='Status', xlabel='Station', ylabel='Period (s)', title='', station_markers=True, tick_every='auto', tick_label_rotation=45.0, tick_fontsize=7, station_tick_config=None, n_yticks=7, figsize=(10.0, 5.2), ax=None)[source]

Station x frequency map of genuinely missing cells for EMImputer.

Parameters:
  • gap_table (DataFrame) – Must contain station, freq, and status_col columns. status_col is 1 where the (station, frequency) cell is genuinely missing (any tensor component NaN) and 0 where every component is observed – build it from a site collection with numpy.isnan(z).any(axis=(1, 2)) per station, one row per frequency (see the imputer user_guide page for a worked example).

  • station_labels (list of str or None)

  • observed_color (str)

  • missing_color (str)

  • period_up (bool, default True)

  • colorbar_label (str)

  • xlabel (str)

  • ylabel (str)

  • title (str)

  • station_markers (bool, default True) – Draw the station axis at the top with pyCSAMT’s shared downward-triangle convention ( PYCSAMT_STATION_RENDERING). Set to False to fall back to a plain bottom axis controlled by tick_every / tick_label_rotation / tick_fontsize / station_tick_config instead.

  • tick_every (int | str) – Only used when station_markers=False.

  • tick_label_rotation (float) – Only used when station_markers=False.

  • tick_fontsize (int) – Only used when station_markers=False.

  • station_tick_config (StationTickConfig | None) – Only used when station_markers=False.

  • n_yticks (int, default 7)

  • figsize ((w, h))

  • ax (Axes or None)

  • status_col (str)

Returns:

ax

Return type:

matplotlib.axes.Axes

pycsamt.ai.processing.plot.plot_imputer_validation(y_true, y_pred, *, component_ids=None, component_labels=None, colors=None, n_cols=2, point_size=10.0, alpha=0.5, show_metrics=True, xlabel='True value', ylabel='Reconstructed value', suptitle='', figsize=None)[source]

Predicted-vs-true scatter for a synthetic held-out-cell validation of EMImputer.

Genuinely missing cells have no known ground truth to compare against, so the standard masked-reconstruction validation protocol instead hides a known fraction of already observed cells, reconstructs them, and compares the reconstruction against the real, held-back values – exactly what this scatter plots.

Parameters:
  • y_true (ndarray, shape (n_points,)) – Flattened true / reconstructed values at synthetically hidden cells only.

  • y_pred (ndarray, shape (n_points,)) – Flattened true / reconstructed values at synthetically hidden cells only.

  • component_ids (ndarray of int, shape (n_points,), or None) – Per-point feature-component index. When given, one panel is drawn per component rather than one shared-axis scatter – log-amplitude and phase channels live on very different scales, and a single pooled RMSE / \(R^2\) (or a single shared axis range) would be dominated by whichever channel has the largest numeric range, the same pooled-metric pitfall documented for EMDenoiser in Learned Spectral Denoising.

  • component_labels (list of str or None) – Panel title for each component_ids value.

  • colors (list of str or None)

  • n_cols (int, default 2) – Panel-grid columns when faceting by component.

  • point_size (float, default 10.0)

  • alpha (float, default 0.5)

  • show_metrics (bool, default True) – Annotate RMSE and \(R^2\) on each panel.

  • xlabel (str)

  • ylabel (str)

  • suptitle (str)

  • figsize ((w, h) or None)

Returns:

fig

Return type:

matplotlib.figure.Figure

pycsamt.ai.processing.plot.plot_imputer_reconstruction(freq, X_raw, X_filled, *, missing_mask=None, station_labels=None, component_labels=None, sites=None, n_show=4, line_color='#2166ac', fill_marker_color='#d62728', fill_marker_size=22.0, log_freq=True, sharey='row', suptitle='', figsize=None)[source]

Per-station, per-channel spectra with reconstructed cells highlighted, for EMImputer.

One column per selected site, one row per feature component, following the (n_sites, n_components, n_freqs) array convention used by prepare_z_features(). The continuous curve is X_filled – observed and reconstructed values alike – with a marker overlaid at every genuinely missing cell, so the reconstructed segment is visually distinct from the real, measured backbone around it.

Parameters:
  • freq (ndarray, shape (n_freqs,)) – Frequency grid in Hz shared by all sites.

  • X_raw (ndarray, shape (n_sites, n_components, n_freqs)) – Data before imputation – only used to infer missing_mask when not given explicitly (~numpy.isfinite(X_raw)).

  • X_filled (ndarray, shape (n_sites, n_components, n_freqs)) – transform() output – the curve actually plotted.

  • missing_mask (ndarray of bool, same shape, or None)

  • station_labels (list of str or None)

  • component_labels (list of str or None)

  • sites (list of int or None) – Explicit site indices to display. Overrides n_show when given.

  • n_show (int, default 4) – Number of sites to display when sites is None – sites with at least one missing cell are preferred, first n_show such sites are used (falling back to the first n_show sites overall when fewer than n_show have any gap).

  • line_color (str)

  • fill_marker_color (str)

  • fill_marker_size (float, default 22.0)

  • log_freq (bool, default True)

  • sharey ("row" | "none", default "row")

  • suptitle (str)

  • figsize ((w, h) or None)

Returns:

fig

Return type:

matplotlib.figure.Figure

pycsamt.ai.processing.plot.plot_imputer_summary(gap_table, freq, X_raw, X_filled, *, missing_mask=None, history=None, station_labels=None, component_labels=None, n_show=2, suptitle='', figsize=(12.0, 11.0))[source]

Combined EMImputer figure: the missing-data map, reconstruction detail for a handful of sites, and (when available) the training curve.

Layout:

┌──────────────────────────────────────────────┐
│  (a) Station x frequency missing-data map     │
├──────────────────────────────────────────────┤
│  (b) Reconstruction detail, n_show sites      │
├──────────────────────────────────────────────┤
│  (c) Training history                         │
└──────────────────────────────────────────────┘

The held-out-cell validation scatter is deliberately not one of these panels – see plot_imputer_validation() and pass it the same y_true/y_pred separately, faceted one panel per feature component, the same reason plot_denoise_spectra() never pools log-amplitude and phase into one shared-axis view.

Parameters:
  • gap_table (DataFrame) – Passed to plot_imputer_gaps().

  • freq (ndarray) – Passed to plot_imputer_reconstruction().

  • X_raw (ndarray) – Passed to plot_imputer_reconstruction().

  • X_filled (ndarray) – Passed to plot_imputer_reconstruction().

  • missing_mask (ndarray | None) – Passed to plot_imputer_reconstruction().

  • station_labels (list[str] | None) – Passed to plot_imputer_reconstruction().

  • component_labels (list[str] | None) – Passed to plot_imputer_reconstruction().

  • history (estimator, dict, or None) – Passed to plot_training_history() when not empty; panel (c) is left blank otherwise.

  • n_show (int, default 2)

  • suptitle (str)

  • figsize ((w, h), default (12.0, 11.0))

Returns:

fig

Return type:

matplotlib.figure.Figure

pycsamt.ai.processing.plot.plot_uncertainty_map(table, *, value_col='z_err_frac_calibrated', station_labels=None, cmap='viridis', vmin=None, vmax=None, period_up=True, n_yticks=7, colorbar_label='Fractional error', xlabel='Station', ylabel='Period (s)', title='', station_markers=True, tick_every='auto', tick_label_rotation=45.0, tick_fontsize=7, station_tick_config=None, figsize=(10.0, 5.2), ax=None)[source]

Station x frequency heat-map of a fractional-error column, for UncertaintyCalibrator.

Colour is log-scaled: fractional error routinely spans more than a decade within one survey, and a linear scale would wash out the low end.

Parameters:
  • table (DataFrame) – Output of UncertaintyCalibrator.predict_table (or build_uncertainty_features_table()). Must contain station, freq, and value_col columns.

  • value_col (str, default "z_err_frac_calibrated") – Column to plot – pass "z_err_frac" instead for the original field-processing fractional error, e.g. to build a matching before/after pair of figures.

  • station_labels (list of str or None)

  • cmap (str, default "viridis")

  • vmin (float or None) – Log-color-scale bounds; None infers both from the data.

  • vmax (float or None) – Log-color-scale bounds; None infers both from the data.

  • period_up (bool, default True)

  • n_yticks (int, default 7)

  • colorbar_label (str)

  • xlabel (str)

  • ylabel (str)

  • title (str)

  • station_markers (bool, default True) – See plot_qc_heatmap().

  • tick_every (int | str) – Only used when station_markers=False.

  • tick_label_rotation (float) – Only used when station_markers=False.

  • tick_fontsize (int) – Only used when station_markers=False.

  • station_tick_config (StationTickConfig | None) – Only used when station_markers=False.

  • figsize ((w, h))

  • ax (Axes or None)

Returns:

ax

Return type:

matplotlib.axes.Axes

pycsamt.ai.processing.plot.plot_uncertainty_validation(y_true, y_pred, *, point_size=10.0, alpha=0.5, show_metrics=True, xlabel='True fractional error', ylabel='Calibrated fractional error', title='', figsize=(5.0, 5.0), ax=None)[source]

Predicted-vs-true scatter for UncertaintyCalibrator.

Same held-out-cell validation idea as plot_imputer_validation(), but for a single unit (fractional error) rather than several feature components, so one shared axis is appropriate here.

Parameters:
  • y_true (ndarray, shape (n_points,)) – Held-out field z_err_frac and the calibrator’s reconstruction of it.

  • y_pred (ndarray, shape (n_points,)) – Held-out field z_err_frac and the calibrator’s reconstruction of it.

  • point_size (float)

  • alpha (float)

  • show_metrics (bool, default True)

  • xlabel (str)

  • ylabel (str)

  • title (str)

  • figsize ((w, h))

  • ax (Axes or None)

Returns:

ax

Return type:

matplotlib.axes.Axes

pycsamt.ai.processing.plot.plot_uncertainty_summary(table, y_true, y_pred, *, history=None, station_labels=None, suptitle='', figsize=(13.0, 10.0))[source]

Combined UncertaintyCalibrator figure: the calibrated-error map, a per-station original-vs.- calibrated comparison, the held-out validation scatter, and (when available) the training curve.

Layout:

┌──────────────────────────────────────────────┐
│ (a) Station x frequency calibrated-error map  │
├───────────────────────┬────────────────────────┤
│ (b) Original vs.      │ (c) Held-out            │
│     calibrated,       │     validation          │
│     per station       │                         │
├───────────────────────┴────────────────────────┤
│ (d) Training history                            │
└──────────────────────────────────────────────┘
Parameters:
  • table (DataFrame) – Output of predict_table(), with both z_err_frac and z_err_frac_calibrated columns – passed to plot_uncertainty_map() for panel (a) and aggregated per station (median) for panel (b).

  • y_true (ndarray) – Passed to plot_uncertainty_validation() for panel (c).

  • y_pred (ndarray) – Passed to plot_uncertainty_validation() for panel (c).

  • history (estimator, dict, or None) – Passed to plot_training_history() when not empty; panel (d) is left blank otherwise.

  • station_labels (list of str or None)

  • suptitle (str)

  • figsize ((w, h), default (13.0, 10.0))

Returns:

fig

Return type:

matplotlib.figure.Figure

pycsamt.ai.processing.plot.plot_distortion_map(table, *, station_labels=None, class_colors=('#2ca02c', '#ff7f0e', '#d62728'), class_labels=('Clean', 'Static-shift-only', 'Distorted'), bar_width=0.8, bar_alpha=0.88, tick_every='auto', tick_label_rotation=45.0, tick_fontsize=7, station_tick_config=None, xlabel='Station', ylabel='Confidence', title='', show_grid=True, figsize=(10.0, 4.0), ax=None)[source]

Per-station distortion-regime bar chart, for DistortionTypeClassifier.

Bar colour encodes the predicted regime (clean / static-shift-only / distorted); bar height is the model’s confidence for that station – both come straight out of predict_table().

Parameters:
  • table (DataFrame) – Output of predict_table(). Must contain station, regime, and confidence columns.

  • station_labels (list of str or None) – Station order; defaults to the table’s own row order.

  • class_colors ((str, str, str)) – Colour and legend label for regimes 0, 1, 2.

  • class_labels ((str, str, str)) – Colour and legend label for regimes 0, 1, 2.

  • bar_width (float)

  • bar_alpha (float)

  • tick_every (int | str) – Station-axis tick control (see StationTickConfig).

  • tick_label_rotation (float) – Station-axis tick control (see StationTickConfig).

  • tick_fontsize (int) – Station-axis tick control (see StationTickConfig).

  • station_tick_config (StationTickConfig | None) – Station-axis tick control (see StationTickConfig).

  • xlabel (str)

  • ylabel (str)

  • title (str)

  • show_grid (bool, default True)

  • figsize ((w, h))

  • ax (Axes or None)

Returns:

ax

Return type:

matplotlib.axes.Axes

pycsamt.ai.processing.plot.plot_distortion_feature_space(table, *, x_col='delta_log10_rho', y_col='twist_deg', shift_th=0.1, twist_th=10.0, class_colors=('#2ca02c', '#ff7f0e', '#d62728'), class_labels=('Clean', 'Static-shift-only', 'Distorted'), point_size=45.0, alpha=0.85, xlabel=None, ylabel=None, title='', show_legend=True, figsize=(6.0, 5.5), ax=None)[source]

Two-feature scatter coloured by predicted distortion regime, for DistortionTypeClassifier.

Shows why a station lands in a given class: with the default axes, delta_log10_rho (resistivity departure from the along- line spatial trend) drives clean/static-shift-only, and twist_deg (Groom-Bailey rotation) drives the distorted class, with the rule-based self-training thresholds drawn as dashed guide lines.

Parameters:
  • table (DataFrame) – Output of predict_table(). Must contain regime plus x_col and y_col.

  • x_col (str, default "delta_log10_rho", "twist_deg")

  • y_col (str, default "delta_log10_rho", "twist_deg")

  • shift_th (float or None) – Rule-based threshold guide lines drawn on the x / y axis respectively (mirrored for negative values where relevant). None skips that guide line – pass None for both when x_col / y_col are not the threshold features.

  • twist_th (float or None) – Rule-based threshold guide lines drawn on the x / y axis respectively (mirrored for negative values where relevant). None skips that guide line – pass None for both when x_col / y_col are not the threshold features.

  • class_colors ((str, str, str))

  • class_labels ((str, str, str))

  • point_size (float)

  • alpha (float)

  • xlabel (str or None) – Default to x_col / y_col.

  • ylabel (str or None) – Default to x_col / y_col.

  • title (str)

  • show_legend (bool, default True)

  • figsize ((w, h))

  • ax (Axes or None)

Returns:

ax

Return type:

matplotlib.axes.Axes

pycsamt.ai.processing.plot.plot_distortion_summary(table, *, history=None, station_labels=None, x_col='delta_log10_rho', y_col='twist_deg', shift_th=0.1, twist_th=10.0, suptitle='', figsize=(12.0, 10.5))[source]

Combined DistortionTypeClassifier figure: the per-station regime map, the feature-space scatter that explains it, class proportions, and (when available) the training curve.

Layout:

┌──────────────────────────────────────────────┐
│ (a) Per-station regime map                    │
├───────────────────────┬────────────────────────┤
│ (b) Feature space     │ (c) Class proportions  │
├───────────────────────┴────────────────────────┤
│ (d) Training history                            │
└──────────────────────────────────────────────┘
Parameters:
  • table (DataFrame) – Output of predict_table().

  • history (estimator, dict, or None) – Passed to plot_training_history() when not empty; panel (d) is left blank otherwise.

  • station_labels (list of str or None)

  • x_col (str) – Passed to plot_distortion_feature_space().

  • y_col (str) – Passed to plot_distortion_feature_space().

  • shift_th (float) – Passed to plot_distortion_feature_space().

  • twist_th (float) – Passed to plot_distortion_feature_space().

  • suptitle (str)

  • figsize ((w, h), default (12.0, 10.5))

Returns:

fig

Return type:

matplotlib.figure.Figure

pycsamt.ai.processing.plot.plot_ts_denoise_mmf_split(t, x, low, high, *, raw_color='#7f7f7f', low_color='#1f77b4', xlabel='Time (s)', suptitle='', figsize=(9.0, 4.6))[source]

Mathematical-morphological-filter (MMF) low/high split.

Mirrors Fig. 8(a)-(d) of Gui et al. (2024): the raw channel with its extracted low-frequency envelope overlaid, and the high-frequency residual carrying any strong interference plus genuine high-frequency signal.

Parameters:
  • t (ndarray, shape (n,)) – Time axis (s).

  • x (ndarray, shape (n,)) – Raw channel and mmf_split() output (low + high == x).

  • low (ndarray, shape (n,)) – Raw channel and mmf_split() output (low + high == x).

  • high (ndarray, shape (n,)) – Raw channel and mmf_split() output (low + high == x).

  • raw_color (str)

  • low_color (str)

  • xlabel (str)

  • suptitle (str)

  • figsize ((w, h))

Returns:

fig

Return type:

matplotlib.figure.Figure

See also

pycsamt.ai.processing.tsdenoise.mmf_split

Producer of low / high.

pycsamt.ai.processing.plot.plot_ts_denoise_segments(t, high, diagnostics, *, color='#7f7f7f', noisy_span_color='#f4c7c3', xlabel='Time (s)', ylabel='Amplitude', title='', figsize=(9.5, 3.2), ax=None)[source]

High-frequency residual with SVM window classification overlaid.

Shades every window SignalQualityClassifier labelled noisy – mirrors Fig. 8(e)-(f)’s SVM-Good / SVM-Noisy split, drawn as one trace with shaded spans rather than two separate panels.

Parameters:
  • t (ndarray, shape (n,))

  • high (ndarray, shape (n,)) – MMF high-frequency residual (see mmf_split()).

  • diagnostics (DataFrame) – diagnostics_ (or a subset filtered to one channel) – columns win_start, win_stop (s), label.

  • color (str)

  • noisy_span_color (str)

  • xlabel (str)

  • ylabel (str)

  • title (str)

  • figsize ((w, h))

  • ax (Axes or None)

Returns:

ax

Return type:

matplotlib.axes.Axes

pycsamt.ai.processing.plot.plot_ts_denoise_summary(t, x, denoised, diagnostics, *, low=None, high=None, raw_color='#7f7f7f', denoised_color='#d62728', noisy_span_color='#f4c7c3', xlabel='Time (s)', suptitle='', figsize=(10.0, 7.0))[source]

Combined before/after summary for TimeSeriesDenoiser.

Three panels: raw channel with SVM-flagged noisy windows shaded, the same windows on the MMF high-frequency residual, and a final raw-vs-denoised overlay – one figure spanning the paper’s Fig. 8(b), (e)-(f), and (g).

Parameters:
  • t (ndarray, shape (n,))

  • x (ndarray, shape (n,)) – Channel before and after apply() / transform().

  • denoised (ndarray, shape (n,)) – Channel before and after apply() / transform().

  • diagnostics (DataFrame) – See plot_ts_denoise_segments().

  • low (ndarray or None) – mmf_split() output for x; when given, the second panel plots high (the residual actually classified) instead of x.

  • high (ndarray or None) – mmf_split() output for x; when given, the second panel plots high (the residual actually classified) instead of x.

  • raw_color (str)

  • denoised_color (str)

  • noisy_span_color (str)

  • xlabel (str)

  • suptitle (str)

  • figsize ((w, h))

Returns:

fig

Return type:

matplotlib.figure.Figure

pycsamt.ai.processing.plot.plot_training_history(history, *, train_key='train_loss', val_key='val_loss', train_label='Train', val_label='Validation', train_color='#1f77b4', val_color='#d62728', log_y=False, mark_best=True, best_color='#2ca02c', xlabel='Epoch', ylabel='Loss', title='', show_legend=True, figsize=(6.0, 4.0), ax=None)[source]

Train/validation loss curve for a pycsamt.ai.processing estimator.

Works with the history_ property exposed after fit() by EMDenoiser, AnomalyDetector, and DimensionalityClassifier — pass either the fitted estimator itself or its history_ dict.

Parameters:
  • history (estimator or dict) – A fitted estimator exposing history_, or a dict with train_key / val_key entries (lists of per-epoch loss values). Estimators trained through a non-network fallback (scipy smoothing, PCA, random forest) have an empty history and raise ValueError.

  • train_key (str) – Dictionary keys holding the per-epoch loss lists.

  • val_key (str) – Dictionary keys holding the per-epoch loss lists.

  • train_label (str)

  • val_label (str)

  • train_color (str)

  • val_color (str)

  • log_y (bool, default False) – Use a log-scaled y-axis — useful when the loss spans more than one order of magnitude early in training.

  • mark_best (bool, default True) – Mark the lowest-validation-loss epoch with a vertical dashed line and an annotation.

  • best_color (str)

  • xlabel (str)

  • ylabel (str)

  • title (str)

  • show_legend (bool, default True)

  • figsize ((w, h), default (6.0, 4.0))

  • ax (Axes or None)

Returns:

ax

Return type:

matplotlib.axes.Axes

Examples

>>> from pycsamt.ai.processing import EMDenoiser
>>> from pycsamt.ai.processing.plot import plot_training_history
>>> den = EMDenoiser().fit(X_clean, epochs=60)
>>> plot_training_history(den, title="Denoiser training")