pycsamt.map#
Code-first station, profile, and 3-D mapping tools for pyCSAMT.
The pycsamt.map package is the reusable mapping layer for
scripts, notebooks, and applications. It accepts the same survey
inputs as pycsamt.emtools._core.ensure_sites(): an EDI
directory, one or more EDI files, EDI-like objects, or a
pycsamt.site.Sites container. For multi-line surveys, use
pycsamt.map.load_lines() or pycsamt.map.MapView.
Quick Use#
Function-style use is compact and works well in notebooks.
from pycsamt.map import (
ProfileMapOptions,
StationMapOptions,
VolumeMapOptions,
plot_pseudosection,
plot_station_map,
plot_volume_map,
)
line = "data/AMT/WILLY_DATA/L18PLT"
station_fig = plot_station_map(
line,
options=StationMapOptions(
overlay="rho",
frequency=10.0,
component="xy",
frequency_tolerance=2.0,
),
)
pseudo_fig = plot_pseudosection(
line,
options=ProfileMapOptions(
quantity="phase",
components=("xy", "yx"),
x_axis="distance",
),
)
volume_fig = plot_volume_map(
line,
options=VolumeMapOptions(
mode="fence",
component="xy",
depth_range=(0.0, 2000.0),
),
)
Builder API#
Builder classes keep one normalized survey in memory and let you create variants without reloading the EDI data.
from pycsamt.map import ProfileMap, StationMap, VolumeMap
station = (
StationMap("data/AMT/WILLY_DATA/L18PLT")
.with_overlay("skin_depth", frequency=10.0)
.with_options(show_labels=False)
.figure()
)
profile = (
ProfileMap("data/AMT/WILLY_DATA/L18PLT")
.with_quantity("rho")
.with_components("xy", "yx")
.pseudosection()
)
volume = (
VolumeMap("data/AMT/WILLY_DATA/L18PLT")
.with_mode("surface")
.with_quantity("phase")
.figure()
)
MapView#
pycsamt.map.MapView is a session facade for code users who
want the same survey to drive station, profile, and 3-D views.
from pycsamt.map import MapView
mv = MapView.from_folder(
"data/AMT/WILLY_DATA",
detect="folder",
)
station = mv.station(overlay="elevation")
pseudo = mv.pseudosection(component="xy")
fence = mv.map3d(mode="fence", depth_range=(0.0, 2000.0))
Export#
Use pycsamt.map.export_figure() for format-aware export, or
the direct helpers for explicit output types.
from pycsamt.map import ExportOptions, export_figure
export_figure(
station,
ExportOptions(path="station.html"),
)
export_figure(
fence,
ExportOptions(path="fence", format="html"),
)
Scientific Note#
The 3-D map modes in pycsamt.map are quick-look
visualizations. Fence, block, depth-slice, and isosurface views use
pseudo-depth grids derived from apparent resistivity and period. They
are useful for inspection and communication, but they are not a
replacement for a constrained 2-D or 3-D inversion model.
Public API#
Code-first mapping API for pyCSAMT surveys.
This package provides reusable station, profile, and 3-D map builders for scripts, notebooks, and applications.
Functions accept the same flexible inputs used by
pycsamt.emtools.ensure_sites: an EDI path, a directory,
an iterable of EDI-like objects, or a Sites instance.
- class pycsamt.map.BasemapConfig(style, center, zoom, bearing=0.0, layers=())#
Bases:
objectPlotly geographic map layout settings.
- class pycsamt.map.ComponentSpec(name, indices=None, mode='tensor')#
Bases:
objectParsed impedance component request.
- class pycsamt.map.CRSConfig(source, target=4326, always_xy=True)#
Bases:
objectCoordinate transform settings.
- pycsamt.map.basemap_style_and_layers(style, *, dark=False)#
Resolve a style name into a (base style, raster layers) pair.
ESRI styles are rendered as
white-bg+ a raster tile layer; native Plotly styles are returned as-is with no layers.
- pycsamt.map.build_geo_contour_image(lons, lats, values, *, cmap='jet', n_levels=12, opacity=0.6, mode='filled+lines', log_scale=False, grid_res=160, expand=0.06, interp='cubic', smooth_sigma=0.0)#
Render a Surfer-style filled-contour PNG for a basemap image layer.
Interpolates sparse station values onto a regular lon/lat grid and rasterises filled (and/or line) contours to a transparent PNG. The result is meant to be added to a Plotly map as an
imagelayer.- Returns:
{"image": "data:image/png;base64,...", "coordinates": [...], "vmin": float, "vmax": float}(coordinates are the TL, TR, BR, BL[lon, lat]corners), orNonewhen it cannot be built.- Return type:
dict | None
- Parameters:
- class pycsamt.map.ExportOptions(path, format=None, width=None, height=None, scale=2.0, include_plotlyjs='cdn')#
Bases:
objectOptions used by figure export helpers.
- Parameters:
- class pycsamt.map.FrequencySelection(requested, actual, index, delta, relative_delta, within_tolerance=True)#
Bases:
objectNearest-frequency selection metadata.
- Parameters:
- class pycsamt.map.FrequencyValue(station, value, selection)#
Bases:
objectStation value and selected-frequency metadata.
- Parameters:
station (str)
value (float)
selection (FrequencySelection)
- selection: FrequencySelection#
- class pycsamt.map.Map3D(data, *, options=None, **ensure_kwargs)#
Bases:
objectBuilder object for 3-D survey maps.
- Parameters:
data (Any)
options (VolumeMapOptions | None)
ensure_kwargs (Any)
- with_options(**kwargs)#
Return a copy with updated options.
- with_quantity(quantity)#
Return a copy using another mapped quantity.
- with_component(component)#
Return a copy using another component.
- class pycsamt.map.MapData(sites, stations=(), profiles=(), metadata=<factory>)#
Bases:
objectNormalized survey data shared by map renderers.
- Parameters:
sites (Any)
stations (tuple[StationRecord, ...])
profiles (tuple[ProfileLine, ...])
- stations: tuple[StationRecord, ...] = ()#
- profiles: tuple[ProfileLine, ...] = ()#
- class pycsamt.map.MapView(data, *, theme='light', backend='plotly')#
Bases:
objectA code-first session bound to one (multi-line) survey.
- classmethod from_folder(path, *, detect='folder', recursive=True, theme='light', backend='plotly', **load_kwargs)#
Build a view from a directory of one or more lines.
- classmethod from_lines(lines, *, theme='light', backend='plotly', **load_kwargs)#
Build a view from an explicit
{line: source}mapping.
- classmethod from_inversion_results(folder, *, known_stations=None, fetch_elevation=True, theme='light', backend='plotly', verbose=0)#
Build a view from a ModEM 3-D inversion result folder.
See
pycsamt.map.inversion.load_modem_lines(). Passknown_stations=existing_view.data.stationsto geo-reference and group ModEM stations using a previously-loaded EDI survey. Passfetch_elevation=Falseto skip the best-effort online elevation lookup (e.g. offline use, or large surveys where the extra round-trip isn’t wanted).
- table()#
Return survey stations as a
pandas.DataFrame.
- with_elevations(elev_map)#
Return a copy with station elevations overridden by elev_map.
- fetch_elevations(*, api_name='open_meteo')#
Fetch station elevations online (see
pycsamt.map.fetch_elevations()).
- export_topography(path, *, fmt=None)#
Export this survey’s station id/elevation/coordinates.
Useful for an EDI-sourced view: a ModEM (or Occam2D/MARE2DEM) inversion result carries no real elevation of its own, so exporting it here produces a small, portable file that can be re-applied later — even in a session that never reloads these EDIs — via the “Upload file” elevation source (see
pycsamt.map.topo.export_elevations()).
- station(*, options=None, **overrides)#
Build a 2-D station map figure.
- Parameters:
options (StationMapOptions | None)
overrides (Any)
- Return type:
- profile(*, options=None, **overrides)#
Build a profile-view figure.
- Parameters:
options (ProfileMapOptions | None)
overrides (Any)
- Return type:
- pseudosection(*, options=None, **overrides)#
Build a resistivity/phase pseudosection figure.
- Parameters:
options (ProfileMapOptions | None)
overrides (Any)
- Return type:
- map3d(*, mode='fence', options=None, **overrides)#
Build a 3-D fence/block/depth/surface figure.
- Parameters:
mode (str)
options (VolumeMapOptions | None)
overrides (Any)
- Return type:
- figure(view='station', **overrides)#
Build a figure for view by name.
- Parameters:
view ({"station", "profile", "pseudosection", "map3d"}) – Which renderer to call.
**overrides – Forwarded to the matching renderer.
- Return type:
- export(path, *, view='station', fmt=None, scale=2.0, width=None, height=None, **overrides)#
Render view and write it to path.
The format is inferred from the suffix unless fmt is given;
.html,.png,.jsonand Plotly static images are supported (seepycsamt.map.export_figure()).
- export_all(directory, *, fmt='html', views=('station', 'pseudosection', 'map3d'), **overrides)#
Export several views into directory, keyed by view name.
- class pycsamt.map.ProfileLine(name, stations=())#
Bases:
objectA named sequence of stations in one profile.
- Parameters:
name (str)
stations (tuple[StationRecord, ...])
- stations: tuple[StationRecord, ...] = ()#
- class pycsamt.map.ProfileMap(data, *, options=None, **ensure_kwargs)#
Bases:
objectBuilder object for profile maps.
- Parameters:
data (Any)
options (ProfileMapOptions | None)
ensure_kwargs (Any)
- with_quantity(quantity)#
Return a copy using another mapped quantity.
- Parameters:
quantity (str)
- Return type:
- with_component(component)#
Return a copy using one impedance component.
- Parameters:
component (str)
- Return type:
- class pycsamt.map.ProfileMapOptions(quantity='rho', component='xy', components=('xy', 'yx'), theme='light', backend='plotly', period_range=None, phase_range=None, value_range=None, x_axis='station', log_rho=True, height_per_panel=260, show_errbar=False, cmap=None)#
Bases:
objectOptions for pseudosection and profile-view maps.
- class pycsamt.map.StationMap(data, *, options=None, **ensure_kwargs)#
Bases:
objectBuilder object for station-map figures.
- Parameters:
data (Any)
options (StationMapOptions | None)
ensure_kwargs (Any)
- with_overlay(overlay, **kwargs)#
Return a copy with a different overlay.
- Parameters:
- Return type:
- class pycsamt.map.StationMapOptions(overlay='index', frequency=None, frequency_tolerance=None, component='xy', theme='light', backend='plotly', selected_id=None, line_filter=None, marker_size=10, basemap=None, cmap='plasma', value_range=None, log_color=False, opacity=0.92, show_labels=True, show_profiles=True, show_contours=False, contour_image=False, contour_mode='filled+lines', contour_levels=12, contour_opacity=0.55, contour_interp='cubic', contour_smooth=1.0, contour_grid_res=150, bearing=0.0, title='')#
Bases:
objectOptions for 2-D station maps.
- Parameters:
overlay (str)
frequency (float | None)
frequency_tolerance (float | None)
component (str)
theme (Literal['light', 'dark', 'publication'])
backend (Literal['plotly', 'matplotlib'])
selected_id (str | None)
marker_size (int)
basemap (str | None)
cmap (str)
log_color (bool)
opacity (float)
show_labels (bool)
show_profiles (bool)
show_contours (bool)
contour_image (bool)
contour_mode (str)
contour_levels (int)
contour_opacity (float)
contour_interp (str)
contour_smooth (float)
contour_grid_res (int)
bearing (float)
title (str)
- class pycsamt.map.StationRecord(id, latitude=None, longitude=None, elevation=None, line=None, index=0, source=None)#
Bases:
objectA normalized station row used by map renderers.
- Parameters:
- class pycsamt.map.VolumeMapOptions(mode='fence', quantity='resistivity', component='xy', theme='light', cmap='RdYlBu_r', depth_range=None, period_range=None, rho_range=None, iso_range=None, value_range=None, log_color=True, opacity=0.85, show_contours=False, show_labels=True, n_slices=5, surface_count=12, line_spacing=1.0, azimuth=0.0, topography=True, show_terrain=True, terrain_opacity=0.7, show_stations=False, station_symbol='diamond', station_size=4, station_color='#1f2937', station_labels=False, aspectmode='data', x_unit='m', depth_unit='m', smooth_sections=True, section_res=100, title='')#
Bases:
objectOptions for 3-D fence, block, and depth-slice maps.
- Parameters:
mode (Literal['fence', 'block', 'depth', 'surface'])
quantity (str)
component (str)
theme (Literal['light', 'dark', 'publication'])
cmap (str)
log_color (bool)
opacity (float)
show_contours (bool)
show_labels (bool)
n_slices (int)
surface_count (int)
line_spacing (float)
azimuth (float)
topography (bool)
show_terrain (bool)
terrain_opacity (float)
show_stations (bool)
station_symbol (str)
station_size (int)
station_color (str)
station_labels (bool)
aspectmode (str)
x_unit (str)
depth_unit (str)
smooth_sections (bool)
section_res (int)
title (str)
- pycsamt.map.apply_elevations(data, elev_map)#
Return a copy of data with station elevations overridden.
- pycsamt.map.build_3d_map(data, options)#
Build the concrete 3-D figure.
- Parameters:
data (MapData)
options (VolumeMapOptions)
- Return type:
- pycsamt.map.build_basemap_layout(lon, lat, *, dark=False, style=None, bearing=0.0)#
Return layout settings for geographic station maps.
- pycsamt.map.build_contour_overlay(x, y, values, *, levels=12, cmap='Viridis', opacity=0.65, grid_size=80, mode='lines')#
Build an interpolated map contour overlay.
Returns a Plotly
Contourtrace on a regular grid.
- pycsamt.map.build_profile_line_overlay(x, y, *, geo=False, name='Profile', color='#2563eb', width=2.0)#
Build a reusable profile-line overlay trace.
- pycsamt.map.build_profile_map(data, options)#
Build the concrete profile-view figure.
- Parameters:
data (MapData)
options (ProfileMapOptions)
- Return type:
- pycsamt.map.build_pseudosection(data, options)#
Build the concrete pseudosection figure.
- Parameters:
data (MapData)
options (ProfileMapOptions)
- Return type:
- pycsamt.map.build_station_map(data, options=None)#
Build a Plotly 2-D station map.
- Parameters:
data (MapData)
options (StationMapOptions | None)
- Return type:
- pycsamt.map.build_station_label_overlay(x, y, labels, *, geo=False, name='Station labels', color='#111827')#
Build a reusable station-label overlay trace.
- pycsamt.map.build_topography_overlay(x, y, elevation, *, opacity=0.7, colorscale='Earth')#
Build a Plotly 3-D terrain mesh or surface.
- pycsamt.map.component_spec(component)#
Return a parsed impedance component specification.
- Parameters:
component (str | None)
- Return type:
- pycsamt.map.ensure_map_data(data, *, recursive=True, line_map=None, verbose=0)#
Return normalized map data.
- Parameters:
data (Any) – EDI path, directory, iterable, or
Sites.recursive (bool) – Passed to
pycsamt.emtools._core.ensure_sites().line_map (dict[str, Iterable[str]] | None) – Optional
line -> station namesmapping used when line metadata is not embedded in EDI objects.verbose (int) – Verbosity passed to
ensure_sites().
- Return type:
- pycsamt.map.export_elevations(data, path, *, fmt=None)#
Export station id/elevation/coordinates to CSV or HDF5.
EDI files carry real, field-surveyed elevation; a ModEM (or Occam2D/MARE2DEM) inversion result does not. Exporting a survey’s EDI-derived topography here produces a small, portable lookup table —
station+elevation(pluslatitude/longitude/linefor provenance) — thatparse_elevation_file()already knows how to read back in. That means it can be applied to an inversion-sourced view later via the “Upload file” elevation source, in a different session that never reloads the original EDIs, matching stations by id (with the same normalized fallback used byapply_elevations()).- Parameters:
data (MapData) – Survey to export (typically EDI-sourced, where
elevationis already populated).path (path-like) – Destination file.
fmtdefaults to the file’s own suffix (.csv/.h5/.hdf5); pass it explicitly to override.fmt ({"csv", "h5", "hdf5"}, optional)
- Returns:
The path written to.
- Return type:
- Raises:
ValueError – If no station in data has a known elevation, or fmt is unsupported.
- pycsamt.map.export_figure(fig, options)#
Export fig according to options.
- Parameters:
fig (Any)
options (ExportOptions)
- Return type:
- pycsamt.map.fetch_elevations(data, *, api_name='open_meteo')#
Fetch station elevations online from their coordinates.
Uses
pycsamt.gis.utils.get_elevation_from_api()(needs an internet connection andrequests).
- pycsamt.map.figure_to_dict(fig)#
Return a serializable figure dictionary.
- pycsamt.map.group_modem_stations(station_names, *, known_stations=None)#
Group ModEM station names into survey lines.
Prefers matching each name against known_stations (e.g. previously loaded EDI stations) and using their
linetag. Falls back to parsing the line token out of the station-name convention{survey}-{line}-{station}{suffix}(e.g.23-18-001A-> line18) — a heuristic, used only when a station has no match in known_stations.
- pycsamt.map.interpolate_overlay_grid(x, y, values, *, grid_size=80, method='linear')#
Interpolate scattered values to a regular grid.
- pycsamt.map.load_lines(source, *, detect='folder', recursive=True, line_map=None, verbose=0)#
Build one combined
MapDatafrom multiple lines.- Parameters:
source (Any) – Mapping, sequence, directory, or file (see module docstring). A
MapDatais returned unchanged.detect ({"folder", "auto", "flat"}, default "folder") –
Line-grouping rule applied only when source is a single directory:
folderOne line per immediate sub-folder holding EDI files (a flat folder becomes one line named after it).
autoGroup by the station-ID prefix, e.g.
22-001->L22.flatTreat the whole directory as a single line.
recursive (bool) – Recurse into sub-directories when discovering EDI files and when calling
ensure_map_data().line_map (dict[str, Iterable[str]] | None) – Optional
line -> station namesmapping forwarded toensure_map_data()for sources without embedded line metadata.verbose (int) – Verbosity forwarded to
ensure_map_data().
- Returns:
Stations from every line, re-indexed and tagged with their resolved line name; profiles are rebuilt per line.
- Return type:
- pycsamt.map.load_modem_lines(folder, *, known_stations=None, fetch_elevation=True, verbose=0)#
Load a ModEM 3-D inversion result folder as a multi-line MapData.
- Parameters:
folder (path-like) – A ModEM output directory. The matching final-iteration
.rho/.datpair is auto-detected bypycsamt.models.modem.results.InversionResult.known_stations (iterable of StationRecord, optional) – Previously-loaded EDI stations (e.g.
existing_map_data.stations) used to geo-reference and group ModEM stations by real coordinates/line name — see the module docstring.fetch_elevation (bool, default True) – ModEM output carries no real elevation (unlike EDI, where it’s already in the file header, so “Drape topography” just works). When
True, any station still missing an elevation afterknown_stationsmatching gets a best-effort online lookup (Open-Meteo) so topography isn’t silently flat by default. Failures (offline, API error, …) are swallowed — elevation simply stays unset, same as passingFalse.verbose (int, default 0) – Verbosity forwarded to the ModEM readers.
- Returns:
sites=None(no EDI backing);stationscarries oneStationRecordper ModEM station with coordinates resolved where possible;metadata["sections"]carries the precomputed per-line(x, z, rho)curtains consumed directly bypycsamt.map.volume.- Return type:
- pycsamt.map.launch_app(source=None, *, host='127.0.0.1', port=8770, debug=False, open_browser=True, theme='light', backend='plotly', detect='folder', recursive=True, **load_kwargs)#
Launch the interactive map-view app.
- Parameters:
source (Any) – Optional survey source.
Nonestarts the welcome screen. Otherwise accepts data, paths, sites, or mappings.host (str) – Forwarded to
pycsamt.app.mapview.launch().port (int) – Forwarded to
pycsamt.app.mapview.launch().debug (bool) – Forwarded to
pycsamt.app.mapview.launch().open_browser (bool) – Forwarded to
pycsamt.app.mapview.launch().detect (str) – Used for path/folder inputs.
recursive (bool) – Used for path/folder inputs.
**load_kwargs (Any) – Extra options forwarded to
MapView.from_folderorload_lines().
- Return type:
None
- pycsamt.map.launch_mapview(source=None, **kwargs)#
Alias for
launch_app().
- pycsamt.map.normalize_component(component)#
Return the canonical map component name.
- pycsamt.map.normalize_epsg(epsg)#
Return an EPSG authority string.
- pycsamt.map.normalize_station_id(name)#
Loosely-normalized station id for fuzzy matching.
Lowercases and strips everything but letters/digits, so minor formatting differences between sources —
23-18-001Avs23_18_001avs23 18 001A— still match. Used as a fallback tier (never the only lookup) wherever a station from one source (EDI, ModEM, an uploaded elevation file, …) needs to be matched against another.
- pycsamt.map.open_app(source=None, **kwargs)#
Backward-compatible alias for
launch_app().
- pycsamt.map.parse_elevation_file(content, filename)#
Parse an uploaded elevation file into
{station_id: elev}.Supports CSV, HDF5 (
.h5/.hdf5) and NPZ. The file must hold a station-id column/array (one ofstation,id,name,sta) and an elevation column/array (elevation,elev,z,alt,altitude,height). Returns{}on any parse failure rather than raising.
- pycsamt.map.plot_3d_map(data, *, options=None, **kwargs)#
Build a 3-D map.
- Parameters:
data (Any)
options (VolumeMapOptions | None)
kwargs (Any)
- Return type:
- pycsamt.map.plot_profile_map(data, *, options=None, **kwargs)#
Build a profile-view map.
- Parameters:
data (Any)
options (ProfileMapOptions | None)
kwargs (Any)
- Return type:
- pycsamt.map.plot_pseudosection(data, *, options=None, **kwargs)#
Build a resistivity or phase pseudosection.
- Parameters:
data (Any)
options (ProfileMapOptions | None)
kwargs (Any)
- Return type:
- pycsamt.map.plot_station_map(data, *, options=None, **kwargs)#
Build a 2-D station map.
- Parameters:
data (Any)
options (StationMapOptions | None)
kwargs (Any)
- Return type:
- pycsamt.map.plot_volume_map(data, *, options=None, **kwargs)#
Build a 3-D volume map.
- Parameters:
data (Any)
options (VolumeMapOptions | None)
kwargs (Any)
- Return type:
- pycsamt.map.reproject_xy_to_lonlat(x, y, *, epsg)#
Reproject x, y from epsg to WGS84 lon/lat.
- pycsamt.map.resolve_crs_info(mode='geo', *, zone=50, hemisphere='N', epsg=4326)#
Return a human-readable CRS description.
- pycsamt.map.resolve_line_groups(source, *, detect='folder', recursive=True)#
Return a
{line_name: source}mapping for source.The values are passed straight to
ensure_map_data(), so they may be directories, lists of file paths, or EDI-like iterables. This mirrors thegroupsstore used by the GUI loader, making the two paths share one grouping contract.
- pycsamt.map.save_png(fig, path, **kwargs)#
Save a Matplotlib-like or Plotly-like figure as PNG.
- pycsamt.map.select_frequency(frequencies, requested=None, *, tolerance=None)#
Select the closest finite positive frequency.
- Parameters:
- Return type:
FrequencySelection | None
- pycsamt.map.transform_xy(x, y, *, crs)#
Transform coordinates between two CRS definitions.
- pycsamt.map.value_at_frequency_details(data, *, frequency, quantity='rho', component='xy', tolerance=None)#
Return values with selected-frequency metadata.
- pycsamt.map.write_html(fig, path, **kwargs)#
Write a Plotly-like figure to HTML.
- pycsamt.map.write_dict(fig, path)#
Write a figure dictionary as JSON text.
- pycsamt.map.write_image(fig, path, **kwargs)#
Write a Plotly-like image.
Modules#
Configuration dataclasses for |
|
Core data extraction helpers for |
|
Multi-line EDI ingestion for |
|
High-level |
|
2-D station-map API for pyCSAMT surveys. |
|
Profile-view and pseudosection API for pyCSAMT surveys. |
|
3-D map API for fence, block, and depth-slice views. |
|
Overlay helpers for station, profile, and 3-D maps. |
|
Style helpers for pyCSAMT map renderers. |
|
Figure export helpers for |
|
Import geophysical inversion results into |
|
Elevation / topography sources for |