PyHydroGeophysX.visualization package#
Submodules#
PyHydroGeophysX.visualization.animation module#
Time-lapse animation utilities for geophysical models.
- PyHydroGeophysX.visualization.animation.create_combined_timelapse_gif(mesh: Any, filename: str, *, wc_models: Sequence[ndarray] | None = None, res_models: Sequence[ndarray] | None = None, app_res_data: Sequence | None = None, precipitation: ndarray | None = None, n_frames: int | None = None, wc_cmap: Any = None, res_cmap: Any = None, app_res_cmap: Any = None, wc_cmin: float = 0.0, wc_cmax: float = 0.32, res_cmin: float = 100, res_cmax: float = 2000, app_res_cmin: float = 100, app_res_cmax: float = 1000, app_res_plot_type: str = 'scatter', app_res_scatter_size: float = 10, mesh_ylim: Tuple[float, float] | None = None, figsize: Tuple[float, float] = (14, 10), dpi: int = 100, duration: int = 100, first_frame_duration: int = 500, loop: int = 0, day_labels: Sequence[str] | None = None) str[source]#
Create a combined GIF with water content, resistivity, apparent resistivity pseudosection, and precipitation panels.
The water content and resistivity model panels are placed side-by-side on the same row.
- Parameters:
mesh (pygimli.Mesh) – Mesh shared by WC and resistivity models.
filename (str) – Output GIF path.
wc_models (sequence of array-like, optional) – Water content model per frame.
res_models (sequence of array-like, optional) – Resistivity model per frame.
app_res_data (sequence, optional) – PyGimli DataContainers (or file paths) of apparent resistivity per frame. Converted to SimPEG internally for pseudosection plotting.
precipitation (array-like, optional) – 1-D precipitation array (length =
n_frames).n_frames (int, optional) – Number of frames. Inferred from whichever data list is provided.
wc_cmap – Colormaps for each panel.
res_cmap – Colormaps for each panel.
app_res_cmap – Colormaps for each panel.
wc_cmin (float) – Water content color limits.
wc_cmax (float) – Water content color limits.
res_cmin (float) – Resistivity color limits.
res_cmax (float) – Resistivity color limits.
app_res_cmin (float) – Apparent resistivity color limits.
app_res_cmax (float) – Apparent resistivity color limits.
app_res_plot_type (str) –
'scatter','pcolor', or'contourf'.mesh_ylim (tuple of (ymin, ymax), optional) – Y-axis limits for the mesh model panels (WC and resistivity). E.g.
(1600, 1720)to crop the vertical range.figsize (tuple) – Figure size per frame.
dpi (int) – Resolution.
duration (int) – Milliseconds per frame.
first_frame_duration (int) – Duration of first frame in ms.
loop (int) – 0 = infinite loop.
day_labels (sequence of str, optional) – Label for each frame (e.g.
'Day 0','Day 1', …).
- Returns:
Path to the saved GIF file.
- Return type:
str
- PyHydroGeophysX.visualization.animation.create_difference_gif(mesh: Any, models: Sequence[ndarray], reference: ndarray, filename: str, *, mode: str = 'difference', titles: Sequence[str] | None = None, cmap: str = 'RdBu_r', symmetric: bool = True, label: str = '', figsize: Tuple[float, float] = (8, 2.5), dpi: int = 150, duration: int = 100, coverage: ndarray | Sequence[ndarray] | None = None) str[source]#
Create a GIF animation showing model changes relative to a reference.
- Parameters:
mesh (pygimli.Mesh)
models (sequence of array-like) – Model snapshots for each frame.
reference (array-like) – Baseline model to subtract / divide.
mode (
'difference'|'ratio'|'percent_change')symmetric (bool) – Center colorbar at zero / one.
:param (other parameters same as
create_timelapse_gif()):- Returns:
Path to the saved GIF file.
- Return type:
str
- PyHydroGeophysX.visualization.animation.create_timelapse_gif(mesh: Any, models: Sequence[ndarray], filename: str, *, titles: Sequence[str] | None = None, cmap: Any = None, cmin: float | None = None, cmax: float | None = None, log_scale: bool = False, label: str = '', xlabel: str = 'Distance (m)', ylabel: str = 'Elevation (m)', coverage: ndarray | Sequence[ndarray] | None = None, figsize: Tuple[float, float] = (8, 2.5), dpi: int = 150, duration: int = 100, first_frame_duration: int = 500, loop: int = 0) str[source]#
Create a GIF animation of time-lapse model snapshots.
Each frame renders the model on the given mesh using
pg.showand captures it as a PIL image. RequiresPillow.- Parameters:
mesh (pygimli.Mesh) – Mesh shared by all models.
models (sequence of array-like) – Model values for each frame.
filename (str) – Output GIF path.
titles (sequence of str, optional) – Title per frame.
cmap (str or Colormap, optional) – Colormap. Defaults to BlueDarkRed18_18_r if available.
cmin (float, optional) – Fixed color limits.
cmax (float, optional) – Fixed color limits.
log_scale (bool) – Logarithmic color scale.
label (str) – Colorbar label.
coverage (array or list of arrays, optional) – Coverage mask(s).
figsize (tuple) – Figure size per frame.
dpi (int) – Resolution.
duration (int) – Milliseconds per frame.
first_frame_duration (int) – Duration of the first frame in ms (longer for visual pause).
loop (int) – Number of loops (0 = infinite).
- Returns:
Path to the saved GIF file.
- Return type:
str
- PyHydroGeophysX.visualization.animation.create_timelapse_mp4(mesh: Any, models: Sequence[ndarray], filename: str, *, titles: Sequence[str] | None = None, cmap: Any = None, cmin: float | None = None, cmax: float | None = None, log_scale: bool = False, label: str = '', xlabel: str = 'Distance (m)', ylabel: str = 'Elevation (m)', coverage: ndarray | Sequence[ndarray] | None = None, figsize: Tuple[float, float] = (8, 2.5), dpi: int = 150, fps: int = 10) str[source]#
Create an MP4 video of time-lapse model snapshots using matplotlib.
Requires
ffmpegto be available on the system path.- Parameters:
mesh (pygimli.Mesh)
models (sequence of array-like)
filename (str) – Output
.mp4path.fps (int) – Frames per second.
:param (other parameters same as
create_timelapse_gif()):- Returns:
Path to the saved MP4 file.
- Return type:
str
PyHydroGeophysX.visualization.basemap module#
Satellite / street basemaps for survey maps drawn in projected metres.
A survey map reads far better over imagery: the reader sees at once that a line ran along a road, across a field, or beside a river. This fetches XYZ raster tiles and warps them onto a matplotlib axes whose units are projected metres (UTM, state plane, a local grid), so the map keeps honest distances instead of being redrawn in Web Mercator, where a metre is not a metre.
Deliberately built on requests + Pillow alone. contextily is the
usual answer and does more (many providers, automatic attribution), but it
brings rasterio and pyproj with it; this package’s other map views need
neither, and a field laptop benefits from an on-disk tile cache more than from
another projection stack.
No projection library is needed because the caller already knows both
coordinates of every station: its projected (x, y) and its (lon, lat).
UTM and Web Mercator are both conformal, so over one survey the map between them
is a similarity transform (one rotation, one scale, one shift) to well under a
metre. fit_local_transform() recovers it by least squares from those pairs.
Tile-server terms of use apply to whatever source is selected. Esri World
Imagery and OpenStreetMap both allow light non-commercial use with attribution,
which basemap_image() returns so the caller can place it on the figure.
Keep requests modest: max_tiles bounds every call, and cached tiles are
never re-fetched.
- PyHydroGeophysX.visualization.basemap.TILE_SOURCES: Dict[str, Dict[str, Any]] = {'Satellite': {'attribution': 'Imagery © Esri, Maxar, Earthstar Geographics', 'max_zoom': 19, 'url': 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'}, 'Street map': {'attribution': '© OpenStreetMap contributors', 'max_zoom': 19, 'url': 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'}, 'Topographic': {'attribution': '© Esri, HERE, Garmin, USGS', 'max_zoom': 19, 'url': 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}'}}#
Tile providers, keyed by the label a UI can show.
urltakesz,xandy; Esri numbers its rows before its columns, hence the order there.
- PyHydroGeophysX.visualization.basemap.basemap_image(x_limits: Sequence[float], y_limits: Sequence[float], *, transform: Tuple[complex, complex], source: str = 'Satellite', target_pixels: int = 900, max_tiles: int = 24, cache_dir: Path | None = None, timeout: float = 8.0) Dict[str, Any] | None[source]#
Imagery for a projected-metre axes, warped onto that axes’ own grid.
transformcomes fromfit_local_transform(). The returned dict holdsimage(an RGB array ready forimshow),extentin the axes’ own units,attribution, andzoom. ReturnsNonewhen the source is unknown, nothing could be fetched, or a dependency is missing, so the caller simply draws no basemap.
- PyHydroGeophysX.visualization.basemap.default_cache_dir() Path[source]#
Where tiles are kept between sessions.
Honours
PYHYDROGEOPHYSX_TILE_CACHEso a shared or read-only machine can redirect it.
- PyHydroGeophysX.visualization.basemap.fetch_mosaic(west: float, south: float, east: float, north: float, *, source: Dict[str, Any], zoom: int, cache_dir: Path | None = None, timeout: float = 8.0) Tuple[ndarray, Tuple[float, float, float, float]] | None[source]#
Stitch the tiles covering a Web Mercator box.
Returns
(rgb, (west, east, south, north))for the mosaic’s own extent, which is a whole number of tiles and so slightly larger than the request.
- PyHydroGeophysX.visualization.basemap.fit_local_transform(x, y, lon, lat) Tuple[complex, complex] | None[source]#
Least-squares similarity from projected metres to Web Mercator metres.
Returns
(a, b)such thatmx + i*my = a * (x + i*y) + b. Written over the complex plane because a complex multiply is a rotation plus a scale, which is exactly the freedom a pair of conformal projections leaves; the fit is then one two-column least squares.Returns
Nonewhen fewer than three usable stations are given or the residual is too large to trust, so the caller can drop the basemap rather than draw imagery in the wrong place.
PyHydroGeophysX.visualization.ert_style module#
Shared plotting convention for inverted ERT resistivity models.
PyHydroGeophysX.visualization.multi_method module#
Visualization helpers for multi-method geophysical workflows.
- PyHydroGeophysX.visualization.multi_method.plot_cross_section_with_wells(result: Any, mesh: Any, well_data: Dict[str, ndarray] | None = None) Any[source]#
Plot a model cross-section and overlay optional well picks.
- PyHydroGeophysX.visualization.multi_method.plot_depth_slices(cells: Any, depths: Any = (5.0, 15.0, 30.0, 50.0), basemap: Any = None, extent: Any = None, max_distance: float | None = None, drop_below_doi: bool = True, grid: int = 400, vmin: float | None = None, vmax: float | None = None, ncols: int = 2, cmap: str = 'turbo', show_stations: bool = False) Any[source]#
Map the recovered resistivity at fixed depths, over a basemap.
cellsis the per-cell table a line inversion writes, needingx,y,depth_center_mandresistivity_ohm_m, and usingbelow_doiwhen it carries one. A pandas frame or any mapping of columns will do.Each requested depth is snapped to the nearest layer the model actually has, and the panel is titled with the depth used rather than the depth asked for. Interpolating between layer centres would invent a resolution the layering does not have.
max_distanceis what keeps the picture honest. A survey of a few lines leaves most of the map with no station anywhere near it, and a triangulated interpolation will happily fill that space from stations hundreds of metres away. Anything further than this from a station is left blank, so the ground that was measured is the ground that is coloured.One width serves every panel, so that a ribbon growing or shrinking between them means the coverage changed rather than the rule did. The mask is about where a station is, and a survey traces the same track at every depth; how far a sounding sees sideways is a question about resolution, which belongs in how the answer is read rather than in which ground gets coloured.
Left unset it is half the deepest slice requested, floored at three times the station spacing, and the figure states the number it used.
drop_below_doiremoves cells the run marked as unresolved before interpolating, so a depth below the investigation depth over part of the survey shows a gap there instead of a colour.Colour is log10 resistivity, with the range taken from the slices drawn so that the panels are comparable to each other.
show_stationsmarks each sounding. It is off because a shallow slice is a ribbon a few metres wide and a marker per station hides the colour it is there to mark; the ribbon already traces the survey.
- PyHydroGeophysX.visualization.multi_method.plot_em_data_fit(times: Any, observed: Any, predicted: Any, uncertainties: Any = None, true_data: Any = None, chi2: float | None = None, time_scale: float = 1000.0, time_label: str = 'Time (ms)', data_label: str = '|Response|', ax: Any = None) Any[source]#
Plot log-log EM data fit similar to TDEM workflow examples.
- PyHydroGeophysX.visualization.multi_method.plot_em_fit_and_residuals(times: Any, observed: Any, predicted: Any, uncertainties: Any, true_data: Any = None, chi2: float | None = None, time_scale: float = 1000.0) Any[source]#
Create side-by-side EM data fit and residual plots.
- PyHydroGeophysX.visualization.multi_method.plot_em_residuals(times: Any, observed: Any, predicted: Any, uncertainties: Any, sigma_bound: float = 2.0, time_scale: float = 1000.0, time_label: str = 'Time (ms)', ax: Any = None) Any[source]#
Plot normalized residuals with +/-sigma bounds.
- PyHydroGeophysX.visualization.multi_method.plot_hydro_vs_geophys(hydro_wc: Any, inverted_wc: Any, mesh: Any = None) Any[source]#
Compare hydrological water content to geophysics-derived water content.
- PyHydroGeophysX.visualization.multi_method.plot_layered_profiles(depth_edges: Any, profiles: Dict[str, Sequence[float]], colors: Sequence[str] | None = None, xscale: str = 'linear') Any[source]#
Plot one or more layered profiles as step-like vertical columns.
- PyHydroGeophysX.visualization.multi_method.plot_multi_method_panel(ert_result: Any, srt_result: Any, em_result: Any, mesh: Any = None) Any[source]#
Plot side-by-side ERT/SRT/EM model panels.
- PyHydroGeophysX.visualization.multi_method.plot_petrophysical_scatter(x: Any, y: Any, color: Any = None, xlabel: str = 'Porosity (-)', ylabel: str = 'Property', color_label: str = 'Saturation (-)', cmap: str = 'Blues', fit_line: bool = True, ax: Any = None) Any[source]#
Plot petrophysical scatter diagnostics with optional trend line.
- PyHydroGeophysX.visualization.multi_method.plot_signal_and_noise(summary: Any, line: int | None = None, moments: Any = ('LM', 'HM'), smooth: int = 21, axes: Any = None) Any[source]#
Draw the measured signal and the absolute noise along a survey line.
Takes what
PyHydroGeophysX.data_processing.em1d.survey_summary()returns. One panel per moment, both on a log axis, plotted against distance along the line.The pair is the point. A station returns fewer usable gates for two reasons that call for opposite readings, and the relative error the file records is the one divided by the other, so it rises either way and cannot separate them. Drawn apart they can be read directly: a signal that falls while the noise holds is evidence about the ground, because a resistive half-space returns dB/dt going as rho**(-3/2) and is genuinely quieter. A noise floor that rises under a steady signal is an instrument or an environment and says nothing about the ground.
smoothis the width of a running mean over stations, which is cosmetic: station-to-station scatter obscures the trend the figure is drawn to show. Set it to 1 to plot the values themselves.lineselects one survey line, and defaults to the first the summary holds. Distance runs from that line’s own first station.
PyHydroGeophysX.visualization.plotting module#
2D plotting utilities for geophysical models and data.
- PyHydroGeophysX.visualization.plotting.plot_apparent_resistivity_pseudosection(data_obj: Any, *, ax: Any = None, plot_type: str = 'scatter', cmap: Any = None, cmin: float | None = None, cmax: float | None = None, scale: str = 'linear', label: str = 'Apparent resistivity ($\\Omega\\cdot$m)', title: str = '', scatter_marker: str = 's', scatter_size: float = 10, mask_topography: bool = True, show_colorbar: bool = True, cbar_opts: Dict | None = None, figsize: Tuple[float, float] = (12, 5), data_locations: bool = False, clean_axes: bool = False, xlabel: str = 'x (m)', ylabel: str = 'Elevation (m)') Tuple[source]#
Plot apparent resistivity pseudosection with topography using SimPEG.
Converts PyGimli ERT data to SimPEG format and uses SimPEG’s
plot_pseudosectionto render a pseudosection that honours surface topography.- Parameters:
data_obj (pygimli.DataContainer, str, or SimPEG Data) – PyGimli ERT data (or file path to a
.dat), or a pre-converted SimPEGDataobject. When a PyGimli object or path is passed the conversion is done automatically.ax (matplotlib.axes.Axes, optional) – Axes to draw on. Created if None.
plot_type (
'scatter'|'pcolor'|'contourf') – Pseudosection rendering style.cmap (str or Colormap, optional) – Colormap. Defaults to
BlueDarkRed18_18(warm-to-cool).cmin (float, optional) – Color limits.
cmax (float, optional) – Color limits.
scale (
'linear'|'log') – Color scale.label (str) – Colorbar label.
title (str) – Axes title.
scatter_marker (str) – Marker style when plot_type=’scatter’.
scatter_size (float) – Marker size when plot_type=’scatter’.
mask_topography (bool) – If True, mask the region above topography.
show_colorbar (bool) – Show the colorbar.
cbar_opts (dict, optional) – Extra keyword arguments forwarded to the colorbar.
figsize (tuple) – Figure size (only used when ax is None).
data_locations (bool) – Show electrode locations on the plot.
clean_axes (bool) – If True, remove spines and ticks for a clean look.
xlabel (str) – Axis labels.
ylabel (str) – Axis labels.
- Return type:
fig, ax, cbar_or_mappable
- PyHydroGeophysX.visualization.plotting.plot_apparent_resistivity_timelapse(data_objs: Any, *, titles: Sequence[str] | None = None, ncols: int = 4, plot_type: str = 'scatter', cmap: Any = None, cmin: float | None = None, cmax: float | None = None, scale: str = 'linear', label: str = 'Apparent resistivity ($\\Omega\\cdot$m)', scatter_marker: str = 's', scatter_size: float = 10, mask_topography: bool = True, figsize_per_panel: Tuple[float, float] = (4.0, 2.5), clean_axes: bool = True, save_path: str | None = None, dpi: int = 100) Tuple[source]#
Plot a multi-panel time-lapse apparent resistivity pseudosection.
- Parameters:
data_objs (sequence) – List of PyGimli DataContainers, file paths, or SimPEG Data objects.
titles (sequence of str, optional) – Panel titles.
ncols (int) – Number of columns.
plot_type (str) –
'scatter','pcolor', or'contourf'.cmap – Colormap and scale parameters.
cmin – Colormap and scale parameters.
cmax – Colormap and scale parameters.
scale – Colormap and scale parameters.
label – Colormap and scale parameters.
figsize_per_panel (tuple) – (width, height) per subplot.
clean_axes (bool) – Remove spines and ticks.
save_path (str, optional) – If given, save the figure to this path.
dpi (int) – Resolution for saving.
- Return type:
fig, axes
- PyHydroGeophysX.visualization.plotting.plot_convergence(chi2_history: Sequence[float], *, ax: Any = None, target_chi2: float = 1.0, ylabel: str = '$\\chi^2$', title: str = 'Inversion Convergence') Tuple[source]#
Plot chi-squared convergence curve.
- Parameters:
chi2_history (sequence of float) – Chi-squared value per iteration.
target_chi2 (float) – Target misfit (plotted as a dashed line).
- Return type:
fig, ax
- PyHydroGeophysX.visualization.plotting.plot_coverage(mesh: Any, coverage: ndarray, *, ax: Any = None, cmap: str = 'YlGn', threshold: float | None = None, title: str = 'Data Coverage') Tuple[source]#
Plot a coverage / sensitivity map.
- Parameters:
mesh (pygimli.Mesh)
coverage (array-like) – Coverage values per cell.
threshold (float, optional) – If given, overlay a contour at this level.
- Return type:
fig, ax, cbar
- PyHydroGeophysX.visualization.plotting.plot_difference_map(mesh: Any, model_a: ndarray, model_b: ndarray, *, mode: str = 'difference', ax: Any = None, cmap: str = 'RdBu_r', symmetric: bool = True, label: str = '', title: str = '', coverage: ndarray | None = None) Tuple[source]#
Plot the difference or ratio between two models.
- Parameters:
mesh (pygimli.Mesh)
model_a (array-like) – Two model arrays.
result = model_b - model_a(difference) ormodel_b / model_a(ratio).model_b (array-like) – Two model arrays.
result = model_b - model_a(difference) ormodel_b / model_a(ratio).mode (
'difference'|'ratio'|'percent_change')symmetric (bool) – If True, center the colorbar at zero (difference) or one (ratio).
coverage (array-like, optional) – Coverage mask.
- Return type:
fig, ax, cbar
- PyHydroGeophysX.visualization.plotting.plot_electrode_layout(positions: Dict[str, ndarray], *, ax: Any = None, color_by: str = 'z', cmap: str = 'terrain', title: str = 'Electrode Layout') Tuple[source]#
Scatter-plot electrode positions colored by elevation.
- Parameters:
positions (dict) – Must contain
'x'and'y'keys; optionally'z'.- Return type:
fig, ax
- PyHydroGeophysX.visualization.plotting.plot_model_section(mesh: Any, values: ndarray, *, ax: Any = None, cmap: Any = None, cmin: float | None = None, cmax: float | None = None, log_scale: bool = False, label: str = '', xlabel: str = 'Distance (m)', ylabel: str = 'Elevation (m)', title: str = '', coverage: ndarray | None = None, orientation: str = 'vertical') Tuple[source]#
Plot a 2D model cross-section on a PyGIMLi mesh.
- Parameters:
mesh (pygimli.Mesh) – The mesh to plot on.
values (array-like) – Cell values (resistivity, velocity, water content, etc.).
ax (matplotlib.axes.Axes, optional) – Axes to draw on. Created if None.
cmap (str or Colormap, optional) – Colormap. Defaults to
BlueDarkRed18_18_rif available.cmin (float, optional) – Color limits.
cmax (float, optional) – Color limits.
log_scale (bool) – Use logarithmic color scaling.
label (str) – Colorbar label.
coverage (array-like, optional) – Coverage array for masking low-sensitivity cells.
orientation (str) – Colorbar orientation (
'vertical'or'horizontal').
- Return type:
fig, ax, cbar
- PyHydroGeophysX.visualization.plotting.plot_monitoring_timeseries(times: ndarray, series: Dict[str, ndarray], *, true_series: Dict[str, ndarray] | None = None, uncertainties: Dict[str, Tuple[ndarray, ndarray]] | None = None, ax: Any = None, ylabel: str = 'Value', title: str = 'Monitoring Point Time Series') Tuple[source]#
Plot estimated (and optionally true) time-series at monitoring points.
- Parameters:
times (array-like) – Time axis.
series (dict of str -> array) – Estimated values keyed by point name.
true_series (dict of str -> array, optional) – True / reference values for comparison (dashed lines).
uncertainties (dict of str -> (lower, upper), optional) – Uncertainty bounds per point for shading.
- Return type:
fig, ax
- PyHydroGeophysX.visualization.plotting.plot_pseudosection_matrix(data_matrix: ndarray, *, ax: Any = None, cmap: Any = None, vmin: float | None = None, vmax: float | None = None, xlabel: str = 'Time', ylabel: str = 'Measurement #', label: str = 'Apparent resistivity ($\\Omega\\cdot$m)', title: str = '') Tuple[source]#
Plot a time-lapse apparent resistivity matrix as a heatmap.
- Parameters:
data_matrix (2-D array) – Shape
(n_times, n_measurements)or similar.- Return type:
fig, ax, im
- PyHydroGeophysX.visualization.plotting.plot_timelapse_snapshots(mesh: Any, models: Sequence[ndarray], *, titles: Sequence[str] | None = None, ncols: int = 4, cmap: Any = None, cmin: float | None = None, cmax: float | None = None, log_scale: bool = False, label: str = '', coverage: ndarray | Sequence[ndarray] | None = None, figsize_per_panel: Tuple[float, float] = (4.0, 2.5)) Tuple[source]#
Plot a grid of time-lapse model snapshots.
- Parameters:
mesh (pygimli.Mesh) – Mesh shared by all snapshots.
models (sequence of array-like) – Model arrays for each timestep.
titles (sequence of str, optional) – Panel titles. Defaults to
'Timestep 1','Timestep 2', …ncols (int) – Number of columns.
cmap – Passed to
pg.show.cmin – Passed to
pg.show.cmax – Passed to
pg.show.log_scale – Passed to
pg.show.label – Passed to
pg.show.coverage (array or sequence of arrays, optional) – Coverage mask(s). If a single 1-D array it is reused for all panels. If 2-D,
coverage[i]is used for panel i.figsize_per_panel (tuple) – (width, height) per subplot panel.
- Return type:
fig, axes
- PyHydroGeophysX.visualization.plotting.plot_topography(topo_grid: ndarray, *, profile_endpoints: List[Tuple[float, float]] | None = None, ax: Any = None, cmap: str = 'terrain', title: str = 'Surface Topography') Tuple[source]#
Plot a 2-D topography grid with optional profile line overlay.
- Parameters:
topo_grid (2-D array) – Elevation raster.
profile_endpoints (list of (row, col) tuples, optional) – If two points are given, draw the profile line.
- Return type:
fig, ax
PyHydroGeophysX.visualization.pyvista_compat module#
Shared PyVista / PyVistaQt setup used by the 3D viewers.
Factored out of the Mesh 3D module so the inversion model viewer can reuse the same VTK shim and the same offscreen guard.
- PyHydroGeophysX.visualization.pyvista_compat.ensure_vtk_matplotlib_shim() None[source]#
Stub the optional
vtkmodules.vtkRenderingMatplotlibmodule when absent.Some VTK builds (conda-forge
vtk-base) omit it, yet pyvista imports it unconditionally for a side effect not needed for mesh display.
- PyHydroGeophysX.visualization.pyvista_compat.try_import_pyvista() Tuple[bool, Any | None, Any | None, str][source]#
Return
(ok, pyvista_module, QtInteractor, error).Disabled under the offscreen Qt platform (headless / –self-test), where constructing a live
QtInteractoraborts the process at the VTK level.
PyHydroGeophysX.visualization.raster module#
Rasterize a pygimli per-cell field onto a regular grid for image display.
Shared by the ERT and seismic modules so an inverted model can be shown in the
interactive ArrayViewer (zoom, colorbar, value read-out) instead of a
static matplotlib PNG. Qt-free so it can run inside a worker thread.
- PyHydroGeophysX.visualization.raster.rasterize_cell_field(mesh: Any, values: Any, nx: int = 260, nz: int = 150) Tuple[ndarray, Tuple[float, float, float, float]][source]#
Interpolate a per-cell
valuesfield onto a regular grid.Returns
(grid, extent)wheregridhas shape(nz, nx)with row 0 at the top of the section andextent = (x0, x1, z0, z1)uses depth (0 at the top of the para-domain, increasing downward). With theArrayViewerdefault inverted Y axis this renders surface-at-top. Cells outside the para-domain stayNaN(transparent), matching the masked matplotlib view.
PyHydroGeophysX.visualization.vtk_export module#
VTK export utilities for ParaView visualization.
- PyHydroGeophysX.visualization.vtk_export.export_mesh_to_vtk(mesh: Any, filename: str, cell_data: Dict[str, ndarray] | None = None) str[source]#
Export a PyGIMLi mesh to VTK unstructured grid format.
This uses PyGIMLi’s built-in
mesh.exportVTKwhen available and then optionally injects extra cell data fields.- Parameters:
mesh (pygimli.Mesh) – The mesh to export.
filename (str) – Output
.vtkpath.cell_data (dict of str -> array, optional) – Additional named cell-data arrays to write.
- Returns:
Path to the written file.
- Return type:
str
- PyHydroGeophysX.visualization.vtk_export.export_points_to_vtk(points: ndarray, scalars: Dict[str, ndarray], filename: str) str[source]#
Export point-cloud data (e.g. cell centers) to VTK PolyData.
- Parameters:
points (array of shape (N, 3)) – XYZ coordinates.
scalars (dict of str -> array) – Named scalar values at each point.
filename (str) – Output
.vtkpath.
- Returns:
Path to the written file.
- Return type:
str
- PyHydroGeophysX.visualization.vtk_export.export_structured_vtk(values: ndarray, filename: str, *, dx: float = 1.0, dy: float = 1.0, dz: float = 1.0, origin: tuple = (0.0, 0.0, 0.0), scalar_name: str = 'model') str[source]#
Export a 3-D numpy array to VTK structured-points format.
Useful for MODFLOW/ParFlow grids that map directly to a regular grid.
- Parameters:
values (3-D array) – Shape
(nz, ny, nx)— layer, row, column ordering.filename (str) – Output
.vtkpath.dx (float) – Cell spacing in each direction.
dy (float) – Cell spacing in each direction.
dz (float) – Cell spacing in each direction.
origin (tuple of float) –
(x0, y0, z0)origin of the grid.scalar_name (str) – Name for the scalar dataset.
- Returns:
Path to the written file.
- Return type:
str
- PyHydroGeophysX.visualization.vtk_export.export_structured_vtk_multi(scalars: Dict[str, ndarray], filename: str, *, dx: float = 1.0, dy: float = 1.0, dz: float = 1.0, origin: tuple = (0.0, 0.0, 0.0)) str[source]#
Export multiple 3-D arrays as named scalars in a single VTK file.
All arrays must have the same shape
(nz, ny, nx).- Parameters:
scalars (dict of str -> 3-D array) – Named scalar datasets (e.g.
{"resistivity": res, "water_content": wc}).filename (str) – Output
.vtkpath.
- Returns:
Path to the written file.
- Return type:
str
- PyHydroGeophysX.visualization.vtk_export.export_timelapse_structured_vtk(models: Sequence[ndarray], output_dir: str, prefix: str = 'timelapse', *, dx: float = 1.0, dy: float = 1.0, dz: float = 1.0, origin: tuple = (0.0, 0.0, 0.0), scalar_name: str = 'model') List[str][source]#
Export time-lapse 3-D arrays as a numbered VTK series.
- Parameters:
models (sequence of 3-D arrays) – Each entry has shape
(nz, ny, nx).output_dir (str) – Output directory.
prefix (str) – File prefix.
dx (float) – Grid spacing.
dy (float) – Grid spacing.
dz (float) – Grid spacing.
origin (tuple) – Grid origin.
scalar_name (str) – Scalar field name.
- Returns:
Paths to generated VTK files.
- Return type:
list of str
- PyHydroGeophysX.visualization.vtk_export.export_timelapse_vtk(mesh: Any, models: Sequence[ndarray], output_dir: str, prefix: str = 'timelapse', *, scalar_name: str = 'model', extra_data: Dict[str, Sequence[ndarray]] | None = None) List[str][source]#
Export time-lapse models as a numbered VTK series for ParaView.
Creates files
prefix_0000.vtk,prefix_0001.vtk, … and a.pvdcollection file that ParaView can load as a time series.- Parameters:
mesh (pygimli.Mesh) – Mesh shared by all timesteps.
models (sequence of array-like) – Model values per timestep.
output_dir (str) – Directory for output files.
prefix (str) – Filename prefix.
scalar_name (str) – Name for the primary scalar field.
extra_data (dict of str -> sequence of arrays, optional) – Additional scalar fields per timestep.
- Returns:
Paths to all generated VTK files.
- Return type:
list of str
Module contents#
Visualization utilities for PyHydroGeophysX.
- PyHydroGeophysX.visualization.create_combined_timelapse_gif(mesh: Any, filename: str, *, wc_models: Sequence[ndarray] | None = None, res_models: Sequence[ndarray] | None = None, app_res_data: Sequence | None = None, precipitation: ndarray | None = None, n_frames: int | None = None, wc_cmap: Any = None, res_cmap: Any = None, app_res_cmap: Any = None, wc_cmin: float = 0.0, wc_cmax: float = 0.32, res_cmin: float = 100, res_cmax: float = 2000, app_res_cmin: float = 100, app_res_cmax: float = 1000, app_res_plot_type: str = 'scatter', app_res_scatter_size: float = 10, mesh_ylim: Tuple[float, float] | None = None, figsize: Tuple[float, float] = (14, 10), dpi: int = 100, duration: int = 100, first_frame_duration: int = 500, loop: int = 0, day_labels: Sequence[str] | None = None) str[source]#
Create a combined GIF with water content, resistivity, apparent resistivity pseudosection, and precipitation panels.
The water content and resistivity model panels are placed side-by-side on the same row.
- Parameters:
mesh (pygimli.Mesh) – Mesh shared by WC and resistivity models.
filename (str) – Output GIF path.
wc_models (sequence of array-like, optional) – Water content model per frame.
res_models (sequence of array-like, optional) – Resistivity model per frame.
app_res_data (sequence, optional) – PyGimli DataContainers (or file paths) of apparent resistivity per frame. Converted to SimPEG internally for pseudosection plotting.
precipitation (array-like, optional) – 1-D precipitation array (length =
n_frames).n_frames (int, optional) – Number of frames. Inferred from whichever data list is provided.
wc_cmap – Colormaps for each panel.
res_cmap – Colormaps for each panel.
app_res_cmap – Colormaps for each panel.
wc_cmin (float) – Water content color limits.
wc_cmax (float) – Water content color limits.
res_cmin (float) – Resistivity color limits.
res_cmax (float) – Resistivity color limits.
app_res_cmin (float) – Apparent resistivity color limits.
app_res_cmax (float) – Apparent resistivity color limits.
app_res_plot_type (str) –
'scatter','pcolor', or'contourf'.mesh_ylim (tuple of (ymin, ymax), optional) – Y-axis limits for the mesh model panels (WC and resistivity). E.g.
(1600, 1720)to crop the vertical range.figsize (tuple) – Figure size per frame.
dpi (int) – Resolution.
duration (int) – Milliseconds per frame.
first_frame_duration (int) – Duration of first frame in ms.
loop (int) – 0 = infinite loop.
day_labels (sequence of str, optional) – Label for each frame (e.g.
'Day 0','Day 1', …).
- Returns:
Path to the saved GIF file.
- Return type:
str
- PyHydroGeophysX.visualization.create_difference_gif(mesh: Any, models: Sequence[ndarray], reference: ndarray, filename: str, *, mode: str = 'difference', titles: Sequence[str] | None = None, cmap: str = 'RdBu_r', symmetric: bool = True, label: str = '', figsize: Tuple[float, float] = (8, 2.5), dpi: int = 150, duration: int = 100, coverage: ndarray | Sequence[ndarray] | None = None) str[source]#
Create a GIF animation showing model changes relative to a reference.
- Parameters:
mesh (pygimli.Mesh)
models (sequence of array-like) – Model snapshots for each frame.
reference (array-like) – Baseline model to subtract / divide.
mode (
'difference'|'ratio'|'percent_change')symmetric (bool) – Center colorbar at zero / one.
:param (other parameters same as
create_timelapse_gif()):- Returns:
Path to the saved GIF file.
- Return type:
str
- PyHydroGeophysX.visualization.create_timelapse_gif(mesh: Any, models: Sequence[ndarray], filename: str, *, titles: Sequence[str] | None = None, cmap: Any = None, cmin: float | None = None, cmax: float | None = None, log_scale: bool = False, label: str = '', xlabel: str = 'Distance (m)', ylabel: str = 'Elevation (m)', coverage: ndarray | Sequence[ndarray] | None = None, figsize: Tuple[float, float] = (8, 2.5), dpi: int = 150, duration: int = 100, first_frame_duration: int = 500, loop: int = 0) str[source]#
Create a GIF animation of time-lapse model snapshots.
Each frame renders the model on the given mesh using
pg.showand captures it as a PIL image. RequiresPillow.- Parameters:
mesh (pygimli.Mesh) – Mesh shared by all models.
models (sequence of array-like) – Model values for each frame.
filename (str) – Output GIF path.
titles (sequence of str, optional) – Title per frame.
cmap (str or Colormap, optional) – Colormap. Defaults to BlueDarkRed18_18_r if available.
cmin (float, optional) – Fixed color limits.
cmax (float, optional) – Fixed color limits.
log_scale (bool) – Logarithmic color scale.
label (str) – Colorbar label.
coverage (array or list of arrays, optional) – Coverage mask(s).
figsize (tuple) – Figure size per frame.
dpi (int) – Resolution.
duration (int) – Milliseconds per frame.
first_frame_duration (int) – Duration of the first frame in ms (longer for visual pause).
loop (int) – Number of loops (0 = infinite).
- Returns:
Path to the saved GIF file.
- Return type:
str
- PyHydroGeophysX.visualization.create_timelapse_mp4(mesh: Any, models: Sequence[ndarray], filename: str, *, titles: Sequence[str] | None = None, cmap: Any = None, cmin: float | None = None, cmax: float | None = None, log_scale: bool = False, label: str = '', xlabel: str = 'Distance (m)', ylabel: str = 'Elevation (m)', coverage: ndarray | Sequence[ndarray] | None = None, figsize: Tuple[float, float] = (8, 2.5), dpi: int = 150, fps: int = 10) str[source]#
Create an MP4 video of time-lapse model snapshots using matplotlib.
Requires
ffmpegto be available on the system path.- Parameters:
mesh (pygimli.Mesh)
models (sequence of array-like)
filename (str) – Output
.mp4path.fps (int) – Frames per second.
:param (other parameters same as
create_timelapse_gif()):- Returns:
Path to the saved MP4 file.
- Return type:
str
- PyHydroGeophysX.visualization.export_mesh_to_vtk(mesh: Any, filename: str, cell_data: Dict[str, ndarray] | None = None) str[source]#
Export a PyGIMLi mesh to VTK unstructured grid format.
This uses PyGIMLi’s built-in
mesh.exportVTKwhen available and then optionally injects extra cell data fields.- Parameters:
mesh (pygimli.Mesh) – The mesh to export.
filename (str) – Output
.vtkpath.cell_data (dict of str -> array, optional) – Additional named cell-data arrays to write.
- Returns:
Path to the written file.
- Return type:
str
- PyHydroGeophysX.visualization.export_points_to_vtk(points: ndarray, scalars: Dict[str, ndarray], filename: str) str[source]#
Export point-cloud data (e.g. cell centers) to VTK PolyData.
- Parameters:
points (array of shape (N, 3)) – XYZ coordinates.
scalars (dict of str -> array) – Named scalar values at each point.
filename (str) – Output
.vtkpath.
- Returns:
Path to the written file.
- Return type:
str
- PyHydroGeophysX.visualization.export_structured_vtk(values: ndarray, filename: str, *, dx: float = 1.0, dy: float = 1.0, dz: float = 1.0, origin: tuple = (0.0, 0.0, 0.0), scalar_name: str = 'model') str[source]#
Export a 3-D numpy array to VTK structured-points format.
Useful for MODFLOW/ParFlow grids that map directly to a regular grid.
- Parameters:
values (3-D array) – Shape
(nz, ny, nx)— layer, row, column ordering.filename (str) – Output
.vtkpath.dx (float) – Cell spacing in each direction.
dy (float) – Cell spacing in each direction.
dz (float) – Cell spacing in each direction.
origin (tuple of float) –
(x0, y0, z0)origin of the grid.scalar_name (str) – Name for the scalar dataset.
- Returns:
Path to the written file.
- Return type:
str
- PyHydroGeophysX.visualization.export_structured_vtk_multi(scalars: Dict[str, ndarray], filename: str, *, dx: float = 1.0, dy: float = 1.0, dz: float = 1.0, origin: tuple = (0.0, 0.0, 0.0)) str[source]#
Export multiple 3-D arrays as named scalars in a single VTK file.
All arrays must have the same shape
(nz, ny, nx).- Parameters:
scalars (dict of str -> 3-D array) – Named scalar datasets (e.g.
{"resistivity": res, "water_content": wc}).filename (str) – Output
.vtkpath.
- Returns:
Path to the written file.
- Return type:
str
- PyHydroGeophysX.visualization.export_timelapse_structured_vtk(models: Sequence[ndarray], output_dir: str, prefix: str = 'timelapse', *, dx: float = 1.0, dy: float = 1.0, dz: float = 1.0, origin: tuple = (0.0, 0.0, 0.0), scalar_name: str = 'model') List[str][source]#
Export time-lapse 3-D arrays as a numbered VTK series.
- Parameters:
models (sequence of 3-D arrays) – Each entry has shape
(nz, ny, nx).output_dir (str) – Output directory.
prefix (str) – File prefix.
dx (float) – Grid spacing.
dy (float) – Grid spacing.
dz (float) – Grid spacing.
origin (tuple) – Grid origin.
scalar_name (str) – Scalar field name.
- Returns:
Paths to generated VTK files.
- Return type:
list of str
- PyHydroGeophysX.visualization.export_timelapse_vtk(mesh: Any, models: Sequence[ndarray], output_dir: str, prefix: str = 'timelapse', *, scalar_name: str = 'model', extra_data: Dict[str, Sequence[ndarray]] | None = None) List[str][source]#
Export time-lapse models as a numbered VTK series for ParaView.
Creates files
prefix_0000.vtk,prefix_0001.vtk, … and a.pvdcollection file that ParaView can load as a time series.- Parameters:
mesh (pygimli.Mesh) – Mesh shared by all timesteps.
models (sequence of array-like) – Model values per timestep.
output_dir (str) – Directory for output files.
prefix (str) – Filename prefix.
scalar_name (str) – Name for the primary scalar field.
extra_data (dict of str -> sequence of arrays, optional) – Additional scalar fields per timestep.
- Returns:
Paths to all generated VTK files.
- Return type:
list of str
- PyHydroGeophysX.visualization.plot_apparent_resistivity_pseudosection(data_obj: Any, *, ax: Any = None, plot_type: str = 'scatter', cmap: Any = None, cmin: float | None = None, cmax: float | None = None, scale: str = 'linear', label: str = 'Apparent resistivity ($\\Omega\\cdot$m)', title: str = '', scatter_marker: str = 's', scatter_size: float = 10, mask_topography: bool = True, show_colorbar: bool = True, cbar_opts: Dict | None = None, figsize: Tuple[float, float] = (12, 5), data_locations: bool = False, clean_axes: bool = False, xlabel: str = 'x (m)', ylabel: str = 'Elevation (m)') Tuple[source]#
Plot apparent resistivity pseudosection with topography using SimPEG.
Converts PyGimli ERT data to SimPEG format and uses SimPEG’s
plot_pseudosectionto render a pseudosection that honours surface topography.- Parameters:
data_obj (pygimli.DataContainer, str, or SimPEG Data) – PyGimli ERT data (or file path to a
.dat), or a pre-converted SimPEGDataobject. When a PyGimli object or path is passed the conversion is done automatically.ax (matplotlib.axes.Axes, optional) – Axes to draw on. Created if None.
plot_type (
'scatter'|'pcolor'|'contourf') – Pseudosection rendering style.cmap (str or Colormap, optional) – Colormap. Defaults to
BlueDarkRed18_18(warm-to-cool).cmin (float, optional) – Color limits.
cmax (float, optional) – Color limits.
scale (
'linear'|'log') – Color scale.label (str) – Colorbar label.
title (str) – Axes title.
scatter_marker (str) – Marker style when plot_type=’scatter’.
scatter_size (float) – Marker size when plot_type=’scatter’.
mask_topography (bool) – If True, mask the region above topography.
show_colorbar (bool) – Show the colorbar.
cbar_opts (dict, optional) – Extra keyword arguments forwarded to the colorbar.
figsize (tuple) – Figure size (only used when ax is None).
data_locations (bool) – Show electrode locations on the plot.
clean_axes (bool) – If True, remove spines and ticks for a clean look.
xlabel (str) – Axis labels.
ylabel (str) – Axis labels.
- Return type:
fig, ax, cbar_or_mappable
- PyHydroGeophysX.visualization.plot_apparent_resistivity_timelapse(data_objs: Any, *, titles: Sequence[str] | None = None, ncols: int = 4, plot_type: str = 'scatter', cmap: Any = None, cmin: float | None = None, cmax: float | None = None, scale: str = 'linear', label: str = 'Apparent resistivity ($\\Omega\\cdot$m)', scatter_marker: str = 's', scatter_size: float = 10, mask_topography: bool = True, figsize_per_panel: Tuple[float, float] = (4.0, 2.5), clean_axes: bool = True, save_path: str | None = None, dpi: int = 100) Tuple[source]#
Plot a multi-panel time-lapse apparent resistivity pseudosection.
- Parameters:
data_objs (sequence) – List of PyGimli DataContainers, file paths, or SimPEG Data objects.
titles (sequence of str, optional) – Panel titles.
ncols (int) – Number of columns.
plot_type (str) –
'scatter','pcolor', or'contourf'.cmap – Colormap and scale parameters.
cmin – Colormap and scale parameters.
cmax – Colormap and scale parameters.
scale – Colormap and scale parameters.
label – Colormap and scale parameters.
figsize_per_panel (tuple) – (width, height) per subplot.
clean_axes (bool) – Remove spines and ticks.
save_path (str, optional) – If given, save the figure to this path.
dpi (int) – Resolution for saving.
- Return type:
fig, axes
- PyHydroGeophysX.visualization.plot_convergence(chi2_history: Sequence[float], *, ax: Any = None, target_chi2: float = 1.0, ylabel: str = '$\\chi^2$', title: str = 'Inversion Convergence') Tuple[source]#
Plot chi-squared convergence curve.
- Parameters:
chi2_history (sequence of float) – Chi-squared value per iteration.
target_chi2 (float) – Target misfit (plotted as a dashed line).
- Return type:
fig, ax
- PyHydroGeophysX.visualization.plot_coverage(mesh: Any, coverage: ndarray, *, ax: Any = None, cmap: str = 'YlGn', threshold: float | None = None, title: str = 'Data Coverage') Tuple[source]#
Plot a coverage / sensitivity map.
- Parameters:
mesh (pygimli.Mesh)
coverage (array-like) – Coverage values per cell.
threshold (float, optional) – If given, overlay a contour at this level.
- Return type:
fig, ax, cbar
- PyHydroGeophysX.visualization.plot_cross_section_with_wells(result: Any, mesh: Any, well_data: Dict[str, ndarray] | None = None) Any[source]#
Plot a model cross-section and overlay optional well picks.
- PyHydroGeophysX.visualization.plot_depth_slices(cells: Any, depths: Any = (5.0, 15.0, 30.0, 50.0), basemap: Any = None, extent: Any = None, max_distance: float | None = None, drop_below_doi: bool = True, grid: int = 400, vmin: float | None = None, vmax: float | None = None, ncols: int = 2, cmap: str = 'turbo', show_stations: bool = False) Any[source]#
Map the recovered resistivity at fixed depths, over a basemap.
cellsis the per-cell table a line inversion writes, needingx,y,depth_center_mandresistivity_ohm_m, and usingbelow_doiwhen it carries one. A pandas frame or any mapping of columns will do.Each requested depth is snapped to the nearest layer the model actually has, and the panel is titled with the depth used rather than the depth asked for. Interpolating between layer centres would invent a resolution the layering does not have.
max_distanceis what keeps the picture honest. A survey of a few lines leaves most of the map with no station anywhere near it, and a triangulated interpolation will happily fill that space from stations hundreds of metres away. Anything further than this from a station is left blank, so the ground that was measured is the ground that is coloured.One width serves every panel, so that a ribbon growing or shrinking between them means the coverage changed rather than the rule did. The mask is about where a station is, and a survey traces the same track at every depth; how far a sounding sees sideways is a question about resolution, which belongs in how the answer is read rather than in which ground gets coloured.
Left unset it is half the deepest slice requested, floored at three times the station spacing, and the figure states the number it used.
drop_below_doiremoves cells the run marked as unresolved before interpolating, so a depth below the investigation depth over part of the survey shows a gap there instead of a colour.Colour is log10 resistivity, with the range taken from the slices drawn so that the panels are comparable to each other.
show_stationsmarks each sounding. It is off because a shallow slice is a ribbon a few metres wide and a marker per station hides the colour it is there to mark; the ribbon already traces the survey.
- PyHydroGeophysX.visualization.plot_difference_map(mesh: Any, model_a: ndarray, model_b: ndarray, *, mode: str = 'difference', ax: Any = None, cmap: str = 'RdBu_r', symmetric: bool = True, label: str = '', title: str = '', coverage: ndarray | None = None) Tuple[source]#
Plot the difference or ratio between two models.
- Parameters:
mesh (pygimli.Mesh)
model_a (array-like) – Two model arrays.
result = model_b - model_a(difference) ormodel_b / model_a(ratio).model_b (array-like) – Two model arrays.
result = model_b - model_a(difference) ormodel_b / model_a(ratio).mode (
'difference'|'ratio'|'percent_change')symmetric (bool) – If True, center the colorbar at zero (difference) or one (ratio).
coverage (array-like, optional) – Coverage mask.
- Return type:
fig, ax, cbar
- PyHydroGeophysX.visualization.plot_electrode_layout(positions: Dict[str, ndarray], *, ax: Any = None, color_by: str = 'z', cmap: str = 'terrain', title: str = 'Electrode Layout') Tuple[source]#
Scatter-plot electrode positions colored by elevation.
- Parameters:
positions (dict) – Must contain
'x'and'y'keys; optionally'z'.- Return type:
fig, ax
- PyHydroGeophysX.visualization.plot_em_data_fit(times: Any, observed: Any, predicted: Any, uncertainties: Any = None, true_data: Any = None, chi2: float | None = None, time_scale: float = 1000.0, time_label: str = 'Time (ms)', data_label: str = '|Response|', ax: Any = None) Any[source]#
Plot log-log EM data fit similar to TDEM workflow examples.
- PyHydroGeophysX.visualization.plot_em_fit_and_residuals(times: Any, observed: Any, predicted: Any, uncertainties: Any, true_data: Any = None, chi2: float | None = None, time_scale: float = 1000.0) Any[source]#
Create side-by-side EM data fit and residual plots.
- PyHydroGeophysX.visualization.plot_em_residuals(times: Any, observed: Any, predicted: Any, uncertainties: Any, sigma_bound: float = 2.0, time_scale: float = 1000.0, time_label: str = 'Time (ms)', ax: Any = None) Any[source]#
Plot normalized residuals with +/-sigma bounds.
- PyHydroGeophysX.visualization.plot_hydro_vs_geophys(hydro_wc: Any, inverted_wc: Any, mesh: Any = None) Any[source]#
Compare hydrological water content to geophysics-derived water content.
- PyHydroGeophysX.visualization.plot_layered_profiles(depth_edges: Any, profiles: Dict[str, Sequence[float]], colors: Sequence[str] | None = None, xscale: str = 'linear') Any[source]#
Plot one or more layered profiles as step-like vertical columns.
- PyHydroGeophysX.visualization.plot_model_section(mesh: Any, values: ndarray, *, ax: Any = None, cmap: Any = None, cmin: float | None = None, cmax: float | None = None, log_scale: bool = False, label: str = '', xlabel: str = 'Distance (m)', ylabel: str = 'Elevation (m)', title: str = '', coverage: ndarray | None = None, orientation: str = 'vertical') Tuple[source]#
Plot a 2D model cross-section on a PyGIMLi mesh.
- Parameters:
mesh (pygimli.Mesh) – The mesh to plot on.
values (array-like) – Cell values (resistivity, velocity, water content, etc.).
ax (matplotlib.axes.Axes, optional) – Axes to draw on. Created if None.
cmap (str or Colormap, optional) – Colormap. Defaults to
BlueDarkRed18_18_rif available.cmin (float, optional) – Color limits.
cmax (float, optional) – Color limits.
log_scale (bool) – Use logarithmic color scaling.
label (str) – Colorbar label.
coverage (array-like, optional) – Coverage array for masking low-sensitivity cells.
orientation (str) – Colorbar orientation (
'vertical'or'horizontal').
- Return type:
fig, ax, cbar
- PyHydroGeophysX.visualization.plot_monitoring_timeseries(times: ndarray, series: Dict[str, ndarray], *, true_series: Dict[str, ndarray] | None = None, uncertainties: Dict[str, Tuple[ndarray, ndarray]] | None = None, ax: Any = None, ylabel: str = 'Value', title: str = 'Monitoring Point Time Series') Tuple[source]#
Plot estimated (and optionally true) time-series at monitoring points.
- Parameters:
times (array-like) – Time axis.
series (dict of str -> array) – Estimated values keyed by point name.
true_series (dict of str -> array, optional) – True / reference values for comparison (dashed lines).
uncertainties (dict of str -> (lower, upper), optional) – Uncertainty bounds per point for shading.
- Return type:
fig, ax
- PyHydroGeophysX.visualization.plot_multi_method_panel(ert_result: Any, srt_result: Any, em_result: Any, mesh: Any = None) Any[source]#
Plot side-by-side ERT/SRT/EM model panels.
- PyHydroGeophysX.visualization.plot_petrophysical_scatter(x: Any, y: Any, color: Any = None, xlabel: str = 'Porosity (-)', ylabel: str = 'Property', color_label: str = 'Saturation (-)', cmap: str = 'Blues', fit_line: bool = True, ax: Any = None) Any[source]#
Plot petrophysical scatter diagnostics with optional trend line.
- PyHydroGeophysX.visualization.plot_pseudosection_matrix(data_matrix: ndarray, *, ax: Any = None, cmap: Any = None, vmin: float | None = None, vmax: float | None = None, xlabel: str = 'Time', ylabel: str = 'Measurement #', label: str = 'Apparent resistivity ($\\Omega\\cdot$m)', title: str = '') Tuple[source]#
Plot a time-lapse apparent resistivity matrix as a heatmap.
- Parameters:
data_matrix (2-D array) – Shape
(n_times, n_measurements)or similar.- Return type:
fig, ax, im
- PyHydroGeophysX.visualization.plot_signal_and_noise(summary: Any, line: int | None = None, moments: Any = ('LM', 'HM'), smooth: int = 21, axes: Any = None) Any[source]#
Draw the measured signal and the absolute noise along a survey line.
Takes what
PyHydroGeophysX.data_processing.em1d.survey_summary()returns. One panel per moment, both on a log axis, plotted against distance along the line.The pair is the point. A station returns fewer usable gates for two reasons that call for opposite readings, and the relative error the file records is the one divided by the other, so it rises either way and cannot separate them. Drawn apart they can be read directly: a signal that falls while the noise holds is evidence about the ground, because a resistive half-space returns dB/dt going as rho**(-3/2) and is genuinely quieter. A noise floor that rises under a steady signal is an instrument or an environment and says nothing about the ground.
smoothis the width of a running mean over stations, which is cosmetic: station-to-station scatter obscures the trend the figure is drawn to show. Set it to 1 to plot the values themselves.lineselects one survey line, and defaults to the first the summary holds. Distance runs from that line’s own first station.
- PyHydroGeophysX.visualization.plot_time_lapse_panel(models: Sequence[Any], mesh: Any = None, titles: Sequence[str] | None = None, ncols: int = 4, cmap: str = 'viridis') Any[source]#
Plot a grid of time-lapse model snapshots.
- PyHydroGeophysX.visualization.plot_timelapse_snapshots(mesh: Any, models: Sequence[ndarray], *, titles: Sequence[str] | None = None, ncols: int = 4, cmap: Any = None, cmin: float | None = None, cmax: float | None = None, log_scale: bool = False, label: str = '', coverage: ndarray | Sequence[ndarray] | None = None, figsize_per_panel: Tuple[float, float] = (4.0, 2.5)) Tuple[source]#
Plot a grid of time-lapse model snapshots.
- Parameters:
mesh (pygimli.Mesh) – Mesh shared by all snapshots.
models (sequence of array-like) – Model arrays for each timestep.
titles (sequence of str, optional) – Panel titles. Defaults to
'Timestep 1','Timestep 2', …ncols (int) – Number of columns.
cmap – Passed to
pg.show.cmin – Passed to
pg.show.cmax – Passed to
pg.show.log_scale – Passed to
pg.show.label – Passed to
pg.show.coverage (array or sequence of arrays, optional) – Coverage mask(s). If a single 1-D array it is reused for all panels. If 2-D,
coverage[i]is used for panel i.figsize_per_panel (tuple) – (width, height) per subplot panel.
- Return type:
fig, axes
- PyHydroGeophysX.visualization.plot_topography(topo_grid: ndarray, *, profile_endpoints: List[Tuple[float, float]] | None = None, ax: Any = None, cmap: str = 'terrain', title: str = 'Surface Topography') Tuple[source]#
Plot a 2-D topography grid with optional profile line overlay.
- Parameters:
topo_grid (2-D array) – Elevation raster.
profile_endpoints (list of (row, col) tuples, optional) – If two points are given, draw the profile line.
- Return type:
fig, ax