visualization package#
Submodules#
PyHydroGeophysX.visualization.axis_units module#
Length units and the vertical axis of a section: metres or feet, elevation or depth.
Every model in the package is computed in metres, and it stays in metres: the meshes, the contour grids, the clip polygons and every exported file. What this module changes is only what an axis shows. A figure drawn “in feet” keeps its data in metres and gets a tick locator and formatter that place round numbers of feet along the axis, so a pyGIMLi mesh drawing, a filled contour and a clip path all line up exactly as before - nothing is re-projected.
The same mechanism turns the vertical axis of a section into depth. A survey
read without elevations puts every electrode at z = 0 and the model below it at
negative z, and labelling that axis “Elevation” presents a made-up datum as a
measured one. When the ground surface is flat at zero, set_section_axes()
labels the axis “Depth” and shows the values positive downward, which is what
pyGIMLi itself does for such a mesh. A section with real topography keeps
“Elevation”.
The unit is a package-wide preference, like a matplotlib rcParam, so one choice
reaches every figure: set_length_unit() sets it, length_unit()
changes it for a block, and every plotting function also takes length_unit
to override it for one call.
Examples
>>> from PyHydroGeophysX.visualization.axis_units import length_label, length_unit
>>> length_label("Distance")
'Distance (m)'
>>> with length_unit("feet"):
... length_label("Distance")
'Distance (ft)'
- PyHydroGeophysX.visualization.axis_units.FEET_PER_METRE = 3.280839895013123#
exactly 0.3048 m.
- Type:
International foot
- PyHydroGeophysX.visualization.axis_units.LENGTH_UNITS: Tuple[str, ...] = ('m', 'ft')#
The units an axis can be shown in.
- PyHydroGeophysX.visualization.axis_units.get_length_unit() str[source]#
The unit figures are drawn in when a call does not name one.
- PyHydroGeophysX.visualization.axis_units.length_factor(unit: str | None = None) float[source]#
Displayed units per metre: 1 for metres, 3.28084 for feet.
- PyHydroGeophysX.visualization.axis_units.length_label(name: str, unit: str | None = None) str[source]#
'Distance (ft)': an axis name with the unit it is shown in.
- PyHydroGeophysX.visualization.axis_units.length_unit(unit: str | None) Iterator[str][source]#
Draw in
unitinside the block, then go back. None leaves it as it is.
- PyHydroGeophysX.visualization.axis_units.normalize_length_unit(unit: str | None = None) str[source]#
'm'or'ft'for any spelling of either; None is the current default.Examples
>>> normalize_length_unit("Feet") 'ft' >>> normalize_length_unit(" metres ") 'm'
- PyHydroGeophysX.visualization.axis_units.pyqtgraph_length_axis(plot: Any, side: str, name: str, *, unit: str | None = None) str[source]#
Label a pyqtgraph
PlotItem/PlotWidgetaxis as a length inunit.pyqtgraph scales an axis’s tick values itself (
AxisItem.setScale) and picks round numbers in the scaled unit, so the data stay in metres here as well. Returns the label text.
- PyHydroGeophysX.visualization.axis_units.resolve_vertical(vertical: str = 'auto', *, mesh: Any = None, surface: Any = None, z: Any = None) str[source]#
'elevation'or'depth': what the vertical axis of a section shows.'auto'gives depth whensection_has_elevation()says the section has no elevation, and elevation otherwise.
- PyHydroGeophysX.visualization.axis_units.section_has_elevation(mesh: Any = None, *, surface: Any = None, z: Any = None) bool[source]#
Whether a section’s vertical coordinate is a real elevation.
False when the ground surface is flat at zero - the geometry a survey gets when it was read without elevations. Give the
mesh, thesurface((x, z)tuple,(n, 2)array or the surface z values) or just the section’szcoordinates, whose top is then taken as the surface. When none of them can be read the answer is True, which keeps the label a section has always had.Examples
>>> section_has_elevation(surface=[0.0, 0.0, 0.0]) False >>> section_has_elevation(surface=[312.4, 310.9, 309.0]) True >>> section_has_elevation(z=[0.0, -5.0, -20.0]) False
- PyHydroGeophysX.visualization.axis_units.section_label_pair(vertical: str = 'auto', *, unit: str | None = None, xlabel: str = 'Distance', mesh: Any = None, surface: Any = None, z: Any = None) Tuple[str, str][source]#
(xlabel, ylabel)text for a section, for code that only sets labels.
- PyHydroGeophysX.visualization.axis_units.set_length_axis(ax: Any, which: str = 'x', name: str = 'Distance', *, unit: str | None = None, depth_reference: float | None = None, labelled: bool = True, **label_kw: Any) str[source]#
Label one axis of
axas a length and tick it inunit.- Parameters:
ax (matplotlib.axes.Axes)
which (
'x','y'or, on 3-D axes,'z')name (str) – The quantity, e.g.
'Distance'or'Depth'; the unit is appended.unit (str, optional) –
'm'or'ft'(any spelling). Defaults toget_length_unit().depth_reference (float, optional) – Show
depth_reference - valueinstead of the value, positive downward: the data are elevations and the axis reads depth below this level.labelled (bool) – Set the label. False leaves it alone - an inner panel of a grid, whose ticks still have to be in the right unit.
**label_kw – Passed to
set_xlabel/set_ylabel(font size, family).
- Returns:
The label text.
- Return type:
str
- PyHydroGeophysX.visualization.axis_units.set_length_unit(unit: str) str[source]#
Draw every figure in
unitfrom now on; returns the previous unit.
- PyHydroGeophysX.visualization.axis_units.set_section_axes(ax: Any, *, mesh: Any = None, surface: Any = None, z: Any = None, vertical: str = 'auto', unit: str | None = None, xlabel: str = 'Distance', depth_reference: float | None = None, label_x: bool = True, label_y: bool = True, elevation_name: str = 'Elevation', depth_name: str = 'Depth', **label_kw: Any) str[source]#
Label and tick both axes of a 2-D section; returns
'elevation'or'depth'.The horizontal axis becomes
xlabelinunit. The vertical one iselevation_nameor, when the section has no elevation (seeresolve_vertical()),depth_nameshown positive downward fromdepth_reference- the top of the ground surface unless given.label_x/label_yFalse keep the ticks in the right unit but leave that label off, for the inner panels of a grid.
- PyHydroGeophysX.visualization.axis_units.to_display_length(values: Any, unit: str | None = None) Any[source]#
A length in metres - scalar or array - converted to
unit.For numbers written into titles and annotations, which no axis formatter reaches.
Examples
>>> round(to_display_length(10.0, "ft"), 3) 32.808
- PyHydroGeophysX.visualization.axis_units.vertical_axis(vertical: str = 'auto', *, mesh: Any = None, surface: Any = None, z: Any = None) Tuple[str, float | None][source]#
(mode, depth_reference)for a section’s vertical axis.modeis asresolve_vertical()decides it. For depth,depth_referenceis the level depth is measured down from - the top of the ground surface, 0 when it cannot be read; for elevation it is None. The surface is read once, so a view can keep the pair and pass it back toset_section_axes()on every redraw.Examples
>>> vertical_axis(z=[0.0, -4.0, -12.0]) ('depth', 0.0) >>> vertical_axis(surface=[102.0, 101.5]) ('elevation', None)
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 | None = None, ylabel: str | None = None, length_unit: str | None = None, vertical: str = 'auto') 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, optional) – Axis labels, used as given. By default
xandElevationinlength_unit- orPseudo-depthwhen the electrodes have no elevation.ylabel (str, optional) – Axis labels, used as given. By default
xandElevationinlength_unit- orPseudo-depthwhen the electrodes have no elevation.length_unit (
'm'|'ft', optional) – Unit the axes are shown in; the data stay in metres.vertical (
'auto'|'elevation'|'depth') – What the vertical axis shows;'auto'gives pseudo-depth when every electrode is at zero elevation.
- 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, length_unit: str | None = None, vertical: str = 'auto') 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.
length_unit – Tick unit and elevation/depth choice, as in
plot_apparent_resistivity_pseudosection(); they matter only withclean_axes=False, since clean axes have no ticks.vertical – Tick unit and elevation/depth choice, as in
plot_apparent_resistivity_pseudosection(); they matter only withclean_axes=False, since clean axes have no ticks.
- 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', length_unit: str | None = None, vertical: str = 'auto') 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.
length_unit – Axis unit and elevation/depth choice, as in
plot_model_section().vertical – Axis unit and elevation/depth choice, as in
plot_model_section().
- 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, length_unit: str | None = None, vertical: str = 'auto') 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.
length_unit – Axis unit and elevation/depth choice, as in
plot_model_section().vertical – Axis unit and elevation/depth choice, as in
plot_model_section().
- 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', length_unit: str | None = None) Tuple[source]#
Scatter-plot electrode positions colored by elevation.
- Parameters:
positions (dict) – Must contain
'x'and'y'keys; optionally'z'.length_unit (
'm'|'ft', optional) – Unit of the axes and of a coordinate colorbar; positions are in metres.
- 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 | None = None, ylabel: str | None = None, title: str = '', coverage: ndarray | None = None, orientation: str = 'vertical', length_unit: str | None = None, vertical: str = 'auto') 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.
xlabel (str, optional) – Axis labels, used as given. By default
DistanceandElevationinlength_unit- orDepth, when the section has no elevation.ylabel (str, optional) – Axis labels, used as given. By default
DistanceandElevationinlength_unit- orDepth, when the section has no elevation.coverage (array-like, optional) – Coverage array for masking low-sensitivity cells.
orientation (str) – Colorbar orientation (
'vertical'or'horizontal').length_unit (
'm'|'ft', optional) – Unit the axes are shown in; the mesh stays in metres. Defaults toget_length_unit().vertical (
'auto'|'elevation'|'depth') – What the vertical axis shows.'auto'gives depth (positive downward) when the ground surface is flat at zero - a survey read without elevations - and elevation otherwise.
- 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), length_unit: str | None = None, vertical: str = 'auto') 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.
length_unit – Axis unit and elevation/depth choice, as in
plot_model_section().vertical – Axis unit and elevation/depth choice, as in
plot_model_section().
- 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', length_unit: str | None = None) 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.
length_unit (
'm'|'ft', optional) – Unit of the elevation colorbar;topo_gridis in metres.
- Return type:
fig, ax
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, *, length_unit: str | None = None, vertical: str = 'auto') Any[source]#
Plot a model cross-section and overlay optional well picks.
Well
x/zare in metres, like the mesh;length_unitandverticalonly change how the axes read, as inplot_multi_method_panel().
- 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, length_unit: str | None = None) 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.length_unit('m'or'ft') is how the axes, the panel depths and the distance note read.depths,extentandmax_distancestay in metres, like the cell table.
- 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, *, length_unit: str | None = None, vertical: str = 'auto') Any[source]#
Compare hydrological water content to geophysics-derived water content.
length_unitandverticalset the section axes, as inplot_multi_method_panel().
- PyHydroGeophysX.visualization.multi_method.plot_layered_profiles(depth_edges: Any, profiles: Dict[str, Sequence[float]], colors: Sequence[str] | None = None, xscale: str = 'linear', length_unit: str | None = None) Any[source]#
Plot one or more layered profiles as step-like vertical columns.
depth_edgesare in metres;length_unit('m'or'ft') is the unit the depth axis is shown in.
- PyHydroGeophysX.visualization.multi_method.plot_multi_method_panel(ert_result: Any, srt_result: Any, em_result: Any, mesh: Any = None, *, length_unit: str | None = None, vertical: str = 'auto') Any[source]#
Plot side-by-side ERT/SRT/EM model panels.
length_unit('m'or'ft') andvertical('auto','elevation'or'depth') set the section axes, as inplot_model_section().
- 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, length_unit: str | None = 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, shown inlength_unit('m'or'ft').
- PyHydroGeophysX.visualization.multi_method.plot_time_lapse_panel(models: Sequence[Any], mesh: Any = None, titles: Sequence[str] | None = None, ncols: int = 4, cmap: str = 'viridis', *, length_unit: str | None = None, vertical: str = 'auto') Any[source]#
Plot a grid of time-lapse model snapshots.
length_unitandverticalset the axes of the panels drawn onmesh, as inplot_multi_method_panel().
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, length_unit: str | None = None, vertical: str = 'auto') 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', …).length_unit (
'm'|'ft', optional) – Unit of the section axes;mesh_ylimstays in metres, like the mesh.vertical (
'auto'|'elevation'|'depth') – What the vertical axes show;'auto'gives depth when the ground surface is flat at zero.
- 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, length_unit: str | None = None, vertical: str = 'auto') str[source]#
Create a GIF animation showing model changes relative to a reference.
Parameters not listed below are the same as in
create_timelapse_gif().- 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.
- 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 | None = None, ylabel: str | None = None, 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, length_unit: str | None = None, vertical: str = 'auto') 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.
xlabel (str, optional) – Axis labels, used as given. By default
DistanceandElevationinlength_unit- orDepth, when the section has no elevation.ylabel (str, optional) – Axis labels, used as given. By default
DistanceandElevationinlength_unit- orDepth, when the section has no elevation.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).
length_unit (
'm'|'ft', optional) – Unit the axes are shown in; the mesh stays in metres.vertical (
'auto'|'elevation'|'depth') – What the vertical axis shows;'auto'gives depth when the ground surface is flat at zero.
- 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 | None = None, ylabel: str | None = None, coverage: ndarray | Sequence[ndarray] | None = None, figsize: Tuple[float, float] = (8, 2.5), dpi: int = 150, fps: int = 10, length_unit: str | None = None, vertical: str = 'auto') str[source]#
Create an MP4 video of time-lapse model snapshots using matplotlib.
Requires
ffmpegto be available on the system path. Parameters not listed below are the same as increate_timelapse_gif().- Parameters:
mesh (pygimli.Mesh)
models (sequence of array-like)
filename (str) – Output
.mp4path.fps (int) – Frames per second.
- Returns:
Path to the saved MP4 file.
- Return type:
str
PyHydroGeophysX.visualization.mt_plots module#
Figures for magnetotelluric data: soundings, models, phase tensors and sections.
Every length - depth, distance along a profile - goes through
axis_units, so the figures follow the package’s metres/feet choice and
read Depth below a flat surface.
- PyHydroGeophysX.visualization.mt_plots.plot_mt_dimensionality(tf: Any, *, axes: Any = None, title: str | None = None) Any[source]#
A site’s phase tensor against period: Φmax and Φmin, the skew β and the strike.
|β|under 3 degrees (shaded) reads as a 1D or 2D response; the strike is ambiguous by 90 degrees and meaningful only where Φmax and Φmin part.axesare three axes sharing x. Returns the figure.
- PyHydroGeophysX.visualization.mt_plots.plot_mt_model_1d(models: Dict[str, Any], *, ax: Any = None, length_unit: str | None = None, max_depth: float | None = None) Any[source]#
Layered resistivity models against depth, one step line each.
modelsmaps a label to anOccam1DResultor a(thickness, resistivity)pair. Returns the figure.
- PyHydroGeophysX.visualization.mt_plots.plot_mt_pseudosection(tfs: Sequence[Any], positions: Sequence[float], *, component: str = 'xy', quantity: str = 'rho', ax: Any = None, length_unit: str | None = None) Any[source]#
Apparent resistivity or phase of one component along a profile, against period.
- PyHydroGeophysX.visualization.mt_plots.plot_mt_section(result: Any, *, ax: Any = None, length_unit: str | None = None, max_depth: float | None = None, limits: Sequence[float] | None = None, cmap: str = 'jet_r', stations: bool = True, title: str | None = None) Any[source]#
A 2D resistivity section from
invert_profile().
- PyHydroGeophysX.visualization.mt_plots.plot_mt_sounding(tf: Any, *, components: Sequence[str] = ('xy', 'yx'), axes: Any = None, predicted: Dict[str, Any] | None = None, title: str | None = None, errors: bool = True) Any[source]#
Apparent resistivity and phase against period, Zyx’s phase folded by 180 degrees.
predictedmaps a component to(period, rho_a, phase)lines drawn over the data - an inversion’s fit. Returns the figure.
- PyHydroGeophysX.visualization.mt_plots.plot_phase_tensor_pseudosection(tfs: Sequence[Any], positions: Sequence[float], *, ax: Any = None, color_by: str = 'phi_min', length_unit: str | None = None, scale: float = 0.4) Any[source]#
Phase-tensor ellipses along a profile against log period.
Each ellipse’s axes are
phi_maxandphi_minnormalized byphi_max, turned toalpha - betafrom north (up); colour iscolor_by("phi_min","beta"skew, …).
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, length_unit: str | None = None, vertical: str = 'auto') 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', …).length_unit (
'm'|'ft', optional) – Unit of the section axes;mesh_ylimstays in metres, like the mesh.vertical (
'auto'|'elevation'|'depth') – What the vertical axes show;'auto'gives depth when the ground surface is flat at zero.
- 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, length_unit: str | None = None, vertical: str = 'auto') str[source]#
Create a GIF animation showing model changes relative to a reference.
Parameters not listed below are the same as in
create_timelapse_gif().- 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.
- 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 | None = None, ylabel: str | None = None, 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, length_unit: str | None = None, vertical: str = 'auto') 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.
xlabel (str, optional) – Axis labels, used as given. By default
DistanceandElevationinlength_unit- orDepth, when the section has no elevation.ylabel (str, optional) – Axis labels, used as given. By default
DistanceandElevationinlength_unit- orDepth, when the section has no elevation.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).
length_unit (
'm'|'ft', optional) – Unit the axes are shown in; the mesh stays in metres.vertical (
'auto'|'elevation'|'depth') – What the vertical axis shows;'auto'gives depth when the ground surface is flat at zero.
- 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 | None = None, ylabel: str | None = None, coverage: ndarray | Sequence[ndarray] | None = None, figsize: Tuple[float, float] = (8, 2.5), dpi: int = 150, fps: int = 10, length_unit: str | None = None, vertical: str = 'auto') str[source]#
Create an MP4 video of time-lapse model snapshots using matplotlib.
Requires
ffmpegto be available on the system path. Parameters not listed below are the same as increate_timelapse_gif().- Parameters:
mesh (pygimli.Mesh)
models (sequence of array-like)
filename (str) – Output
.mp4path.fps (int) – Frames per second.
- 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.get_length_unit() str[source]#
The unit figures are drawn in when a call does not name one.
- PyHydroGeophysX.visualization.length_unit(unit: str | None) Iterator[str][source]#
Draw in
unitinside the block, then go back. None leaves it as it is.
- 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 | None = None, ylabel: str | None = None, length_unit: str | None = None, vertical: str = 'auto') 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, optional) – Axis labels, used as given. By default
xandElevationinlength_unit- orPseudo-depthwhen the electrodes have no elevation.ylabel (str, optional) – Axis labels, used as given. By default
xandElevationinlength_unit- orPseudo-depthwhen the electrodes have no elevation.length_unit (
'm'|'ft', optional) – Unit the axes are shown in; the data stay in metres.vertical (
'auto'|'elevation'|'depth') – What the vertical axis shows;'auto'gives pseudo-depth when every electrode is at zero elevation.
- 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, length_unit: str | None = None, vertical: str = 'auto') 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.
length_unit – Tick unit and elevation/depth choice, as in
plot_apparent_resistivity_pseudosection(); they matter only withclean_axes=False, since clean axes have no ticks.vertical – Tick unit and elevation/depth choice, as in
plot_apparent_resistivity_pseudosection(); they matter only withclean_axes=False, since clean axes have no ticks.
- 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', length_unit: str | None = None, vertical: str = 'auto') 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.
length_unit – Axis unit and elevation/depth choice, as in
plot_model_section().vertical – Axis unit and elevation/depth choice, as in
plot_model_section().
- Return type:
fig, ax, cbar
- PyHydroGeophysX.visualization.plot_cross_section_with_wells(result: Any, mesh: Any, well_data: Dict[str, ndarray] | None = None, *, length_unit: str | None = None, vertical: str = 'auto') Any[source]#
Plot a model cross-section and overlay optional well picks.
Well
x/zare in metres, like the mesh;length_unitandverticalonly change how the axes read, as inplot_multi_method_panel().
- 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, length_unit: str | None = None) 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.length_unit('m'or'ft') is how the axes, the panel depths and the distance note read.depths,extentandmax_distancestay in metres, like the cell table.
- 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, length_unit: str | None = None, vertical: str = 'auto') 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.
length_unit – Axis unit and elevation/depth choice, as in
plot_model_section().vertical – Axis unit and elevation/depth choice, as in
plot_model_section().
- 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', length_unit: str | None = None) Tuple[source]#
Scatter-plot electrode positions colored by elevation.
- Parameters:
positions (dict) – Must contain
'x'and'y'keys; optionally'z'.length_unit (
'm'|'ft', optional) – Unit of the axes and of a coordinate colorbar; positions are in metres.
- 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, *, length_unit: str | None = None, vertical: str = 'auto') Any[source]#
Compare hydrological water content to geophysics-derived water content.
length_unitandverticalset the section axes, as inplot_multi_method_panel().
- PyHydroGeophysX.visualization.plot_layered_profiles(depth_edges: Any, profiles: Dict[str, Sequence[float]], colors: Sequence[str] | None = None, xscale: str = 'linear', length_unit: str | None = None) Any[source]#
Plot one or more layered profiles as step-like vertical columns.
depth_edgesare in metres;length_unit('m'or'ft') is the unit the depth axis is shown in.
- 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 | None = None, ylabel: str | None = None, title: str = '', coverage: ndarray | None = None, orientation: str = 'vertical', length_unit: str | None = None, vertical: str = 'auto') 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.
xlabel (str, optional) – Axis labels, used as given. By default
DistanceandElevationinlength_unit- orDepth, when the section has no elevation.ylabel (str, optional) – Axis labels, used as given. By default
DistanceandElevationinlength_unit- orDepth, when the section has no elevation.coverage (array-like, optional) – Coverage array for masking low-sensitivity cells.
orientation (str) – Colorbar orientation (
'vertical'or'horizontal').length_unit (
'm'|'ft', optional) – Unit the axes are shown in; the mesh stays in metres. Defaults toget_length_unit().vertical (
'auto'|'elevation'|'depth') – What the vertical axis shows.'auto'gives depth (positive downward) when the ground surface is flat at zero - a survey read without elevations - and elevation otherwise.
- 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_mt_dimensionality(tf: Any, *, axes: Any = None, title: str | None = None) Any[source]#
A site’s phase tensor against period: Φmax and Φmin, the skew β and the strike.
|β|under 3 degrees (shaded) reads as a 1D or 2D response; the strike is ambiguous by 90 degrees and meaningful only where Φmax and Φmin part.axesare three axes sharing x. Returns the figure.
- PyHydroGeophysX.visualization.plot_mt_model_1d(models: Dict[str, Any], *, ax: Any = None, length_unit: str | None = None, max_depth: float | None = None) Any[source]#
Layered resistivity models against depth, one step line each.
modelsmaps a label to anOccam1DResultor a(thickness, resistivity)pair. Returns the figure.
- PyHydroGeophysX.visualization.plot_mt_pseudosection(tfs: Sequence[Any], positions: Sequence[float], *, component: str = 'xy', quantity: str = 'rho', ax: Any = None, length_unit: str | None = None) Any[source]#
Apparent resistivity or phase of one component along a profile, against period.
- PyHydroGeophysX.visualization.plot_mt_section(result: Any, *, ax: Any = None, length_unit: str | None = None, max_depth: float | None = None, limits: Sequence[float] | None = None, cmap: str = 'jet_r', stations: bool = True, title: str | None = None) Any[source]#
A 2D resistivity section from
invert_profile().
- PyHydroGeophysX.visualization.plot_mt_sounding(tf: Any, *, components: Sequence[str] = ('xy', 'yx'), axes: Any = None, predicted: Dict[str, Any] | None = None, title: str | None = None, errors: bool = True) Any[source]#
Apparent resistivity and phase against period, Zyx’s phase folded by 180 degrees.
predictedmaps a component to(period, rho_a, phase)lines drawn over the data - an inversion’s fit. Returns the figure.
- PyHydroGeophysX.visualization.plot_multi_method_panel(ert_result: Any, srt_result: Any, em_result: Any, mesh: Any = None, *, length_unit: str | None = None, vertical: str = 'auto') Any[source]#
Plot side-by-side ERT/SRT/EM model panels.
length_unit('m'or'ft') andvertical('auto','elevation'or'depth') set the section axes, as inplot_model_section().
- 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_phase_tensor_pseudosection(tfs: Sequence[Any], positions: Sequence[float], *, ax: Any = None, color_by: str = 'phi_min', length_unit: str | None = None, scale: float = 0.4) Any[source]#
Phase-tensor ellipses along a profile against log period.
Each ellipse’s axes are
phi_maxandphi_minnormalized byphi_max, turned toalpha - betafrom north (up); colour iscolor_by("phi_min","beta"skew, …).
- 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, length_unit: str | None = 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, shown inlength_unit('m'or'ft').
- PyHydroGeophysX.visualization.plot_time_lapse_panel(models: Sequence[Any], mesh: Any = None, titles: Sequence[str] | None = None, ncols: int = 4, cmap: str = 'viridis', *, length_unit: str | None = None, vertical: str = 'auto') Any[source]#
Plot a grid of time-lapse model snapshots.
length_unitandverticalset the axes of the panels drawn onmesh, as inplot_multi_method_panel().
- 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), length_unit: str | None = None, vertical: str = 'auto') 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.
length_unit – Axis unit and elevation/depth choice, as in
plot_model_section().vertical – Axis unit and elevation/depth choice, as in
plot_model_section().
- 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', length_unit: str | None = None) 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.
length_unit (
'm'|'ft', optional) – Unit of the elevation colorbar;topo_gridis in metres.
- Return type:
fig, ax