pycsamt.interp.plot#
plot — visualization for pycsamt.interp results.
Three plot classes cover the main interpretation deliverables:
PlotStratigraphicLog— single-station pseudo-stratigraphic log in the style of Fig. 5d / Fig. 7 of Kouadio et al. (2022).PlotFenceDiagram— multi-station panel with all logs arranged along the profile.PlotCalibratedModel— side-by-side CRM vs NM with the misfit G (%) map overlaid.
All classes follow the same pattern:
fig = PlotStratigraphicLog(log).plot()
fig.savefig("S17_log.png", dpi=200)
Classes
|
Dar-Zarrouk profile — TR, S, water table, and transmissivity. |
|
Compare CRM vs NM and display the G (%) misfit map. |
|
Multi-station fence diagram of pseudo-stratigraphic logs. |
|
2-D hydrogeological section from an |
|
Grid of EM sections at successive time steps — Fig. |
|
ρ vs φ scatter colored by Sw with the fitted Archie/WS model curve. |
|
1-D resistivity depth profile with zone shading — Fig. |
|
Single-station pseudo-stratigraphic log. |
|
Difference section for time-lapse EM monitoring. |
|
Posterior histograms of key hydro quantities per station. |
|
Profile plot: water-table depth and transmissivity with P10–P90 envelopes. |
|
Two-panel section showing the P50 estimate and the uncertainty spread. |
|
Profile plot: water-table depth and transmissivity along the section. |
- class pycsamt.interp.plot.PlotStratigraphicLog(log, *, figsize=(8, 10), depth_unit='m', title=None, annotation_kws=None)[source]#
Bases:
objectSingle-station pseudo-stratigraphic log.
Reproduces the two-panel layout of Fig. 5d / Fig. 7 in Kouadio et al. (2022):
Left panel — colour / hatch blocks for each geological layer with lithology annotations and thickness values.
Right panel — log₁₀(ρ) depth curve overlaid on the same depth axis.
- Parameters:
log (StratigraphicLog)
figsize (tuple)
depth_unit (str) – Label for the depth axis (default
'm').title (str, optional)
annotation_kws (dict, optional) – Extra keyword arguments passed to
ax.annotate.
- class pycsamt.interp.plot.PlotFenceDiagram(logs, *, figsize=None, title='Fence Diagram', max_depth=None)[source]#
Bases:
objectMulti-station fence diagram of pseudo-stratigraphic logs.
Plots every log as a vertical panel side by side, sharing the depth axis, so the lateral geological evolution along the profile is immediately visible.
- Parameters:
logs (list of StratigraphicLog) – Ordered list of station logs (West → East, or South → North).
figsize (tuple, optional) – Defaults to
(2 * n_logs, 10).title (str, optional)
max_depth (float, optional) – Truncate display at this depth (metres).
- class pycsamt.interp.plot.PlotCalibratedModel(crm, nm, misfit_map=None, *, figsize=(12, 10), cmap_rho='jet', vmin_rho=1.0, vmax_rho=5.0, title=None)[source]#
Bases:
objectCompare CRM vs NM and display the G (%) misfit map.
Three sub-plots stacked vertically:
CRM — original inversion result (log₁₀ρ colour image)
NM — calibrated New Model (same colour scale)
Misfit G (%) — diverging colour scale highlighting where the model was corrected the most
- Parameters:
crm (ResistivityModel) – Original CRM.
nm (ResistivityModel) – Calibrated NM from
calibrated_model().misfit_map (ndarray (n_z, n_x), optional) – G (%) array from
misfit_map(). IfNone, computed from the difference between nm and crm.figsize (tuple)
cmap_rho (str) – Matplotlib colourmap for the resistivity panels.
vmin_rho (float) – Colour-scale limits for log₁₀(ρ).
vmax_rho (float) – Colour-scale limits for log₁₀(ρ).
title (str, optional)
- class pycsamt.interp.plot.PlotHydroSection(result, quantity='K', *, style=None, cmap=None, vmin=None, vmax=None, show_water_table=True, figsize=None, title=None, depth_min=None, depth_max=None)[source]#
Bases:
object2-D hydrogeological section from an
EMHydroResult.Renders a colour-image cross-section of one quantitative hydro map (hydraulic conductivity K, water saturation Sw, or porosity φ) with optional overlays:
Water-table line — dashed blue line at the estimated WT depth.
Station markers — thin vertical tick-marks at each profile station.
- Parameters:
result (EMHydroResult) – Quantitative hydro output from
EMHydroModel.quantity (str) – Which map to display:
'K'— hydraulic conductivity (log₁₀ scale),'saturation'— water saturation Sw,'porosity'— effective porosity φ.cmap (str) – Matplotlib colourmap. Defaults: K →
'viridis', Sw →'RdYlBu', φ →'YlOrRd'.vmin (float, optional) – Colour-scale limits. Auto-derived from the data if
None.vmax (float, optional) – Colour-scale limits. Auto-derived from the data if
None.show_water_table (bool) – Overlay the water-table depth profile (default
True).figsize (tuple)
title (str, optional)
depth_min (float, optional) – Start display at this depth (m). Use to zoom past near-surface artefacts and push a shallow water-table line into view.
depth_max (float, optional) – Truncate display at this depth (m).
style (_StyleArg)
Examples
>>> fig = PlotHydroSection(result, quantity='K').plot() >>> fig = PlotHydroSection(result, quantity='saturation', ... cmap='Blues', vmin=0, vmax=1).plot()
- class pycsamt.interp.plot.PlotWaterTableProfile(result, *, style=None, color_wt=None, color_T=None, reference_depth=None, figsize=None, title=None)[source]#
Bases:
objectProfile plot: water-table depth and transmissivity along the section.
Two stacked panels share the same x-axis (profile distance):
Top — water-table depth (m) as a stem/bar plot. Shallower is better; the y-axis is inverted so deep values plot downward.
Bottom — transmissivity T (m²/s) on a log₁₀ scale.
- Parameters:
result (EMHydroResult)
figsize (tuple)
color_wt (str) – Colour for the water-table bars (default
'steelblue').color_T (str) – Colour for the transmissivity bars (default
'seagreen').reference_depth (float, optional) – Draw a horizontal dashed line at this depth on the WT panel (e.g. a known piezometric level).
title (str, optional)
style (_StyleArg)
Examples
>>> fig = PlotWaterTableProfile(result, reference_depth=20.0).plot()
- class pycsamt.interp.plot.PlotTimeLapseSection(timelapse, quantity='rho', *, style=None, survey_idx=0, baseline_idx=0, petro=None, rho_w=20.0, phi=0.25, cmap=None, vmax=None, show_water_table=True, figsize=None, title=None, depth_max=None)[source]#
Bases:
objectDifference section for time-lapse EM monitoring.
Shows Δlog₁₀(ρ) or Δ*Sw* between a selected survey and the baseline as a diverging colour image, allowing rapid visual identification of zones that became more conductive (wetting) or more resistive (drying).
- Parameters:
timelapse (TimeLapseEM) – Time-lapse container holding all surveys.
quantity (str) –
'rho'— raw resistivity change Δlog₁₀ρ (default).'saturation'— saturation change ΔSw (requires petro and rho_w).survey_idx (int) – Index of the comparison survey in
timelapse.surveysrelative to the baseline (default 0 → first non-baseline survey).baseline_idx (int) – Index of the baseline survey (default 0).
petro (ArchieModel, optional) – Required when
quantity='saturation'.rho_w (float) – Pore-water resistivity for saturation inversion (default 20 Ω·m).
phi (float or ndarray) – Porosity for Archie inversion (default 0.25).
cmap (str) – Diverging colourmap (default
'RdBu_r'). Positive (blue) → resistivity increase / drying. Negative (red) → resistivity decrease / wetting.vmax (float, optional) – Symmetric colour-scale limit. Auto-derived from the 98th percentile of
|data|ifNone.show_water_table (bool) – Overlay the water-table profile from the comparison survey.
figsize (tuple)
title (str, optional)
depth_max (float, optional)
style (_StyleArg)
Examples
>>> from pycsamt.interp.timelapse import TimeLapseEM >>> tl = TimeLapseEM([model_dry, model_wet], labels=['dry', 'wet']) >>> fig = PlotTimeLapseSection(tl, quantity='rho').plot() >>> fig = PlotTimeLapseSection( ... tl, quantity='saturation', ... petro=ArchieModel(), rho_w=20.0 ... ).plot()
- class pycsamt.interp.plot.PlotUncertaintySection(unc, quantity='K', *, style=None, cmap_p50=None, cmap_spread=None, vmin_p50=None, vmax_p50=None, vmax_spread=None, show_water_table=True, figsize=None, title=None, depth_min=None, depth_max=None)[source]#
Bases:
objectTwo-panel section showing the P50 estimate and the uncertainty spread.
Panel layout:
Top — P50 (median) of the selected quantity as a colour image.
Bottom — Uncertainty spread: either the coefficient of variation (CV = std/mean, for K) or the P90–P10 range (for Sw, porosity).
- Parameters:
unc (UncertaintyResult)
quantity (str) –
'K'(default) — hydraulic conductivity (log₁₀ scale for P50, CV for spread).'saturation'— Sw (P50 and P90–P10 range).'porosity'— φ (P50 and P90–P10 range).cmap_p50 (str) – Colourmap for the P50 panel (defaults mirror
PlotHydroSection).cmap_spread (str) – Colourmap for the spread panel (default
'hot_r'— dark = high uncertainty).vmin_p50 (float, optional) – Colour limits for P50 panel.
vmax_p50 (float, optional) – Colour limits for P50 panel.
vmax_spread (float, optional) – Upper colour limit for the spread panel. Auto if
None.show_water_table (bool) – Overlay median water-table on both panels (default
True).figsize (tuple)
title (str, optional)
depth_min (float, optional) – Start display at this depth (m) — mirrors
PlotHydroSection.depth_max (float, optional)
style (_StyleArg)
Examples
>>> fig = PlotUncertaintySection(unc_result, quantity='K').plot() >>> fig = PlotUncertaintySection(unc_result, quantity='saturation', ... depth_max=200.0).plot()
- class pycsamt.interp.plot.PlotUncertaintyProfile(unc, *, style=None, color_wt=None, color_T=None, reference_depth=None, figsize=None, title=None)[source]#
Bases:
objectProfile plot: water-table depth and transmissivity with P10–P90 envelopes.
Four data series are shown along the profile x-axis:
Top panel — water-table depth. Shaded band = P10–P90 range; solid line = P50 median. Optional reference depth.
Bottom panel — log₁₀(T). Shaded band = P10–P90; solid line = P50.
- Parameters:
unc (UncertaintyResult)
figsize (tuple)
color_wt (str) – Colour for the water-table envelope (default
'steelblue').color_T (str) – Colour for the transmissivity envelope (default
'seagreen').reference_depth (float, optional) – Horizontal reference line on the WT panel.
title (str, optional)
style (_StyleArg)
Examples
>>> fig = PlotUncertaintyProfile(unc_result, reference_depth=20.0).plot()
- class pycsamt.interp.plot.PlotPetrophysicalCrossPlot(result, *, style=None, petro=None, color_by='saturation', show_hs_bounds=True, rho_matrix=5000.0, depth_range=None, Sw_for_curve=None, log_rho=True, figsize=None, title=None)[source]#
Bases:
objectρ vs φ scatter colored by Sw with the fitted Archie/WS model curve.
Reproduces the cross-plot of Fig. 3b/3c in Chen et al. (2026) for EM data. Each point is one model cell; the colour encodes water saturation (or depth). The petrophysical model curve is drawn at the mean observed saturation. Hashin-Shtrikman bounds are optionally shown as a shaded envelope — no existing tool combines all three in one panel.
- Parameters:
result (EMHydroResult)
petro (ArchieModel or WaxmanSmitsModel, optional) – Defaults to
result.config.petro.color_by (str) –
'saturation'(default) or'depth'.show_hs_bounds (bool) – Overlay Hashin-Shtrikman bounds (default
True).rho_matrix (float) – Rock-matrix resistivity for HS bounds (Ω·m; default 5 000).
depth_range ((float, float), optional) – Restrict to this depth window (m).
Sw_for_curve (float, optional) – Sw value used to draw the model curve. Defaults to mean(Sw).
log_rho (bool) – Log₁₀ scale on the y-axis (default
True).style (_StyleArg)
title (str | None)
- class pycsamt.interp.plot.PlotAquiferCharacterization(result, *, style=None, show_transmissivity=True, log_TR=True, reference_depth=None, figsize=None, title=None)[source]#
Bases:
objectDar-Zarrouk profile — TR, S, water table, and transmissivity.
Three or four stacked panels with a shared profile-distance x-axis:
TR = Σρᵢhᵢ (Ω·m²) — aquifer productivity indicator. Threshold line at
sty.tr_threshold.S = Σhᵢ/ρᵢ (siemens) — clay-seal protective capacity. Narain-Mehrotra class lines at
sty.s_threshold_moderateandsty.s_threshold_good.WT — water-table depth (m).
T — log₁₀(T) (m²/s), optional.
- Parameters:
result (EMHydroResult)
show_transmissivity (bool) – Add a fourth T panel (default
True).log_TR (bool) – Use a log₁₀ y-axis for the TR panel (default
True). Recommended when a resistive basement dominates TR and compresses the productive-aquifer bars to near-zero on a linear scale.reference_depth (float, optional) – Horizontal dashed line on the WT panel.
style (_StyleArg)
title (str | None)
- class pycsamt.interp.plot.PlotMultiTimeLapseGrid(timelapse, quantity='rho', *, style=None, surveys=None, baseline_idx=0, petro=None, rho_w=20.0, phi=0.25, vmin=None, vmax=None, depth_max=None, figsize_panel=None, title=None)[source]#
Bases:
objectGrid of EM sections at successive time steps — Fig. 5c/5d equivalent.
N mini-sections in one row, shared colourbar on the right.
- Parameters:
timelapse (TimeLapseEM)
quantity (str) –
'rho'— absolute log₁₀ρ.'delta_rho'— Δlog₁₀ρ from baseline (diverging).'delta_saturation'— ΔSw from baseline (requires petro).surveys (list of int, optional) – Survey indices to show (default: all).
baseline_idx (int) – Baseline for delta quantities (default 0).
petro – Petrophysics for saturation conversion.
rho_w (float) – Petrophysics for saturation conversion.
phi (float) – Petrophysics for saturation conversion.
vmin (float, optional)
vmax (float, optional)
depth_max (float, optional)
figsize_panel ((w, h), optional) – Size of each mini panel.
style (_StyleArg)
title (str | None)
- class pycsamt.interp.plot.PlotResistivityDepthProfile(source, station=0, *, style=None, depth_max=None, show_zones=True, borehole=None, log_rho=True, figsize=None, title=None)[source]#
Bases:
object1-D resistivity depth profile with zone shading — Fig. 3a equivalent.
Plots the EM inversion ρ(z) curve at one station with a fill and optional hydraulic zone shading derived from an
EMHydroResult.- Parameters:
source (ResistivityModel or EMHydroResult)
depth_max (float, optional)
show_zones (bool) – Shade aquifer / vadose / basement zones from EMHydroResult (
True).borehole (Borehole, optional) – If given, a narrow borehole panel is added on the right.
log_rho (bool) – Log-scale x-axis (default
True).style (_StyleArg)
title (str | None)
- class pycsamt.interp.plot.PlotUncertaintyHistogram(unc, quantity='water_table', *, style=None, stations=None, wt_ensemble=None, T_ensemble=None, show_kde=True, show_percentiles=True, log_x=None, ncols=None, figsize=None, title=None)[source]#
Bases:
objectPosterior histograms of key hydro quantities per station.
Shows the full MC posterior for water-table depth or transmissivity at up to 6 stations, with histogram bars, optional KDE, and P10/P50/P90 vertical lines. When raw ensemble arrays are not passed, a Gaussian approximation is drawn from the stored statistics.
- Parameters:
unc (UncertaintyResult)
quantity (str) –
'water_table'(default) or'transmissivity'.stations (list of str or int, optional) – Stations to display (default: up to 6 evenly spaced).
show_kde (bool)
show_percentiles (bool)
log_x (bool, optional) – Log scale (default
Truefor T,Falsefor WT).ncols (int) – Subplot columns (default min(n_sta, 3)).
style (_StyleArg)
title (str | None)