2.30.7.9. pycsamt.map.styles#

Style helpers for pyCSAMT map renderers.

Functions

geology_colorbar_ticks(bands)

Return (tickvals, ticktext) labelling each band by name.

geology_colorscale(bands, *[, log_lo, ...])

Build a hard-stepped Plotly colorscale from a geology legend.

geology_crange(bands)

Return the (log10_lo, log10_hi) span covered by bands.

geology_legend_shapes_annotations(bands, *)

Build a non-overlapping on-canvas geology legend: one coloured "chip" annotation per band, stacked at a fixed row height in the figure's right margin (xref="paper", so the caller must reserve real margin space -- e.g. margin=dict(r=220)).

is_dark_theme([theme])

Return True for dark map styling.

pattern_band_stops(base_color[, n])

Return n hex colours from a light tint of base_color ("no ink" -- a pattern stencil's background) to the full base_color ("full ink"), for texturing one geology band with a pattern stencil sampled to a per-cell density in [0, 1].

theme_colors([theme])

Return a copied color palette for theme.

to_plotly_cmap(cmap[, fallback])

Return a Plotly colour scale for cmap.

pycsamt.map.styles.to_plotly_cmap(cmap, fallback='plasma')[source]

Return a Plotly colour scale for cmap.

A Plotly name when Plotly has one; otherwise the matplotlib colormap sampled into an explicit scale, so every entry of pycsamt.api.colormaps.COLORMAPS (gist_earth, bwr, Spectral_r …) renders in the 3-D and map views instead of failing.

Parameters:
  • cmap (str | None)

  • fallback (str)

pycsamt.map.styles.geology_crange(bands)[source]

Return the (log10_lo, log10_hi) span covered by bands.

bands is a plain, format-agnostic (rho_min, rho_max, color) list in linear Ω·m – the app layer builds it from a pycsamt.geology.lithology.RockDatabase / pycsamt.format.geology.GeologyLegend; this module stays free of any format/geology import. Non-positive or degenerate bands are ignored. Falls back to (0.0, 1.0) when no band is usable.

Parameters:

bands (Sequence[tuple[float, float, str]])

Return type:

tuple[float, float]

pycsamt.map.styles.geology_colorscale(bands, *, log_lo=None, log_hi=None, gap_color='#9aa0a6', textured=None)[source]

Build a hard-stepped Plotly colorscale from a geology legend.

Returns [[t, color], ...] stops with t in [0, 1] normalized against (log_lo, log_hi) (defaults to geology_crange() of bands), using repeated t values at each band boundary so Plotly renders flat colour bands instead of a smooth gradient – pass the same (log_lo, log_hi) as cmin/cmax on the trace, in log10(Ω·m), so the bands line up with the data. Any part of the [log_lo, log_hi] span not covered by a band (including gaps between bands) renders as gap_color rather than an interpolated blend of neighbouring lithology colours.

textured optionally maps a band’s name (its 4th tuple element) to a stop count – that band’s sub-range is filled with an N-stop pattern_band_stops() gradient (light tint of the band colour -> full colour) instead of one flat colour. On its own this still just renders a gradient; the actual pattern only appears once the caller also overrides each cell’s colour-axis value within that sub-range by a real spatial pattern-stencil sample (see pycsamt.map.volume._inject_pattern_values()) instead of its raw resistivity – this function only prepares the palette that sampling then reads from.

Parameters:
Return type:

list[list]

pycsamt.map.styles.pattern_band_stops(base_color, n=16)[source]

Return n hex colours from a light tint of base_color (“no ink” – a pattern stencil’s background) to the full base_color (“full ink”), for texturing one geology band with a pattern stencil sampled to a per-cell density in [0, 1].

A tile is read purely as a grayscale/alpha stencil (see pycsamt.geology.patterns() tile handling), not as a literal colour source – the legend’s own assigned colour is what actually tints the rendered pattern, so a hatch/stipple/brick swatch reads in the same colour its legend chip already shows, whatever the source pack’s original ink colour was.

Parameters:
Return type:

list[str]

pycsamt.map.styles.geology_colorbar_ticks(bands)[source]

Return (tickvals, ticktext) labelling each band by name.

bands is the same list geology_colorscale() takes, with an optional 4th element, the band’s display name (e.g. a rock name). Each tick sits at the band’s own log10 geometric-mean resistivity so it lands inside its colour, not on a boundary shared with its neighbour. Bands with no name (a plain 3-tuple) are skipped – pass this straight to a trace’s colorbar=dict(tickvals=..., ticktext= ...) in place of the default numeric Ω·m ticks, “masking” the resistivity reading with the geology legend itself.

Parameters:

bands (Sequence[tuple[float, float, str] | tuple[float, float, str, str]])

Return type:

tuple[list[float], list[str]]

pycsamt.map.styles.geology_legend_shapes_annotations(bands, *, x=1.02, y_top=0.95, row_height=0.05, min_row_height=0.026, font_size=11, min_font_size=8)[source]

Build a non-overlapping on-canvas geology legend: one coloured “chip” annotation per band, stacked at a fixed row height in the figure’s right margin (xref="paper", so the caller must reserve real margin space – e.g. margin=dict(r=220)).

Unlike labelling each band at its own resistivity position on a colourbar (geology_colorbar_ticks()), row position here is by index, not by value – two bands whose resistivity ranges sit close together (or a legend with many entries on a short colourbar) can never overlap, only ever crowd, and rows shrink toward min_row_height/min_font_size before that happens. If even the minimum still cannot fit every band in [0, y_top], the remainder collapses into one final “+N more” row rather than overlapping or running off the canvas.

Returns (shapes, annotations) – shapes is always empty (the chip’s own background covers the swatch), kept for API symmetry with a future non-text legend element.

Parameters:
Return type:

tuple[list[dict], list[dict]]

pycsamt.map.styles.theme_colors(theme='light')[source]

Return a copied color palette for theme.

Parameters:

theme (Literal['light', 'dark', 'publication'])

Return type:

dict[str, str]

pycsamt.map.styles.is_dark_theme(theme='light')[source]

Return True for dark map styling.

Parameters:

theme (Literal['light', 'dark', 'publication'])

Return type:

bool