tephpy.plotting.isopleths#
Isopleth families for the tephigram projection (spec §3.2).
Each of the five background families — isotherms, isobars, dry adiabats,
moist adiabats, and humidity mixing-ratio lines — is drawn by one
zoom-aware IsoplethFamily artist. Member polylines are precomputed
as bare numpy arrays over a generous physical domain (the _constants
domains), mapped once into the tephigram x-y data space, and cached on the
artist; every draw selects the members appropriate to the current view and
zoom ladder and re-places the family’s labels. The curved families delegate
their moist thermodynamics to MetPy behind function-local imports so that
import tephpy stays light (spec §10 item 10). The design is derived
from the published tephigram construction with tephi as a corroborating
oracle, not ported from tephi (spec §3.1/§10 item 5).
Units are diagram-native (spec §5 exemption): pressure in hPa, temperatures and potential temperatures in degrees Celsius, mixing ratios in g/kg.
Attributes#
Classes#
One isopleth polyline in tephigram x-y data space. |
|
A family's fully resolved settings snapshot. |
|
Static wiring of one isopleth family: builder plus conventions. |
|
One zoom-aware background isopleth family (spec §3.2). |
Functions#
|
Return where a member polyline meets one edge of the view. |
|
Build isotherm polylines (lines of constant temperature). |
|
Build dry-adiabat polylines (lines of constant potential temperature). |
|
Build isobar polylines (lines of constant pressure). |
|
Build moist-adiabat (pseudoadiabat) polylines. |
|
Build humidity mixing-ratio polylines (isohumes). |
Module Contents#
- tephpy.plotting.isopleths.edge_crossings(xy: numpy.typing.NDArray[numpy.float64], edge: str, view: matplotlib.transforms.Bbox) numpy.typing.NDArray[numpy.float64][source]#
Return where a member polyline meets one edge of the view.
Pure numpy over the cached member geometry: each segment that straddles the edge’s level contributes one linearly interpolated crossing, kept only when it falls within the edge’s own span. A vertex lying exactly on the edge counts once — attributed to the segment it starts, or to the segment it ends when it is the polyline’s last vertex; a segment with a non-finite endpoint never counts. A member may cross the same edge more than once — a curved isobar leaving and re-entering the view — and every crossing is returned (spec §3.2).
- Parameters:
- xy
numpy.ndarray The member polyline, shape
(n, 2)in tephigram data space.- edge
str The edge to intersect, one of
EDGES.- view
matplotlib.transforms.Bbox The current data-space view rectangle.
- xy
- Returns:
numpy.ndarrayThe along-edge coordinates of the crossings — x for
"bottom"and"top", y for"left"and"right"— in polyline order; empty when the member does not reach the edge.
- Raises:
- class tephpy.plotting.isopleths.Member[source]#
One isopleth polyline in tephigram x-y data space.
valueis the member’s isopleth value in the family’s native units (°C, hPa, or g/kg);xyis the(N, 2)float64 polyline.- xy: numpy.typing.NDArray[numpy.float64]#
- tephpy.plotting.isopleths.isotherm_members(values: numpy.typing.ArrayLike) list[Member][source]#
Build isotherm polylines (lines of constant temperature).
Isotherms are exactly straight in the tephigram plane; each member spans
THETA_DOMAINat its constant temperature.
- tephpy.plotting.isopleths.dry_adiabat_members(values: numpy.typing.ArrayLike) list[Member][source]#
Build dry-adiabat polylines (lines of constant potential temperature).
Dry adiabats are exactly straight in the tephigram plane, perpendicular to the isotherms; each member spans
TEMPERATURE_DOMAINat its constant potential temperature.
- tephpy.plotting.isopleths.isobar_members(values: numpy.typing.ArrayLike) list[Member][source]#
Build isobar polylines (lines of constant pressure).
Pressure is a derived curve on the tephigram, not an axis: each member traces Poisson’s equation across
TEMPERATURE_DOMAINat its constant pressure.
- tephpy.plotting.isopleths.moist_adiabat_members(values: numpy.typing.ArrayLike, truncation: float = MOIST_ADIABAT_TRUNCATION) list[Member][source]#
Build moist-adiabat (pseudoadiabat) polylines.
Each member is labelled by its wet-bulb potential temperature — the temperature where the curve crosses
P_REF— and is integrated overPRESSURE_DOMAINwithmetpy.calc.moist_lapse()in a single vectorized call, then truncated where the temperature falls below truncation (the curves converge onto the dry adiabats; Met Office Factsheet 13 convention). Members with fewer than two remaining vertices are dropped.
- tephpy.plotting.isopleths.mixing_ratio_members(values: numpy.typing.ArrayLike) list[Member][source]#
Build humidity mixing-ratio polylines (isohumes).
For a mixing ratio
wthe member traces the dew-point temperature at which the saturation mixing ratio equalsw, sampled acrossPRESSURE_DOMAIN:Td = dewpoint(vapor_pressure(p, w))via MetPy.
- class tephpy.plotting.isopleths.ResolvedOptions[source]#
A family’s fully resolved settings snapshot.
Resolution precedence: accessor kwargs >
tephpy.config>_constants(spec §3.5).values/intervalofNonemean the zoom-adaptive default ladder is in force. An empty label_edges means the family labels inline only, and an empty emphasis means no member is distinguished. The snapshot is immutable throughout: the class is frozen against rebinding, and emphasis – its one field with any container depth – is a read-only proxy at both levels over dicts the family copied for itself when it resolved.- emphasis: collections.abc.Mapping[float, collections.abc.Mapping[str, object]]#
- class tephpy.plotting.isopleths.FamilySpec[source]#
Static wiring of one isopleth family: builder plus conventions.
Exactly one of (
domain+steps) for interval families or (values+strides) for list families is set.
- class tephpy.plotting.isopleths.IsoplethFamily(spec: FamilySpec, section: object, validate: collections.abc.Callable[[str, ResolvedOptions], None] | None = None, on_change: collections.abc.Callable[[], None] | None = None)[source]#
Bases:
matplotlib.artist.ArtistOne zoom-aware background isopleth family (spec §3.2).
Member polylines are built lazily on first draw and cached; each draw clips the cache to the current view rectangle, selects the members appropriate to the zoom level via the family’s convention ladder, and re-places the member labels. Settings resolve as accessor kwargs >
tephpy.config>_constants, read when the family is created or reconfigured (spec §3.5); explicitvaluesorintervalfixes the member set and disables the zoom ladder.- Parameters:
- spec
FamilySpec The family’s static wiring (builder plus convention defaults).
- section
object The family’s
tephpy.configsection, read at creation and onconfigure().- validate
callable(), optional Called with
(family name, candidate options)whenever the options resolve; raising rejects the change. The owning axes passes its one-family-per-edge check here so the rejection lands inside this class’s rollback (spec §3.2).- on_change
callable(), optional Called with no arguments after the options resolve successfully, whichever entry point resolved them. The owning axes passes its edge-ownership sync here so a direct
configure()orset_visible()reaches it too (spec §3.2).
- spec
- property options: ResolvedOptions#
The resolved settings snapshot currently in force.
- Returns:
ResolvedOptionsThe snapshot (accessor kwargs >
tephpy.config>_constants) taken at creation or the lastconfigure().
- configure(**kwargs: object) None[source]#
Reconfigure the family (the accessor-kwargs precedence tier).
Re-reads
tephpy.confignow (spec §3.5 semantics), so any tier may move — a geometry option changed there takes effect on the next call whether or not that call mentions it, and the cached members are rebuilt whenever the resolved geometry differs. PassingNonefor an option removes any prior override so the value falls back totephpy.configand then_constants. A call that raises leaves the family unchanged, and only a call that succeeds notifies the owner’son_change— which is how an edge claimed or released here reaches the diagram (spec §3.2).- Parameters:
- **kwargs
object Options to override; the family’s accessor documents the accepted names.
- **kwargs
- Raises:
TypeErrorIf an option name is unknown for this family, if
labelsnames an unknown placement, or if the owning axes rejects an edge claim already held by another family, or ifemphasisis malformed.ValueErrorIf an option value is invalid, e.g. a non-positive
interval.
- set_visible(b: bool) None[source]#
Show or hide the family, resolving its options as it goes.
The inherited
Artist.set_visibleonly flips a flag; an isopleth family’s visibility is one of its resolved options, and an invisible family draws nothing so it holds no edge (spec §3.2). Hiding is thereforeconfigure(visible=False), which releases any claimed edge, and showing isconfigure(visible=True), which reclaims it. Setting the value the family already has changes nothing, exactly as the base class does.- Parameters:
- bbool
Whether the family is drawn.
- Raises:
TypeErrorIf showing the family would reclaim an edge another family took while it was hidden; the family stays hidden (see
configure()).
- set_figure(fig: matplotlib.figure.Figure | matplotlib.figure.SubFigure) None[source]#
Propagate the owning figure to the managed child artists.
- Parameters:
- fig
matplotlib.figure.Figureormatplotlib.figure.SubFigure The figure the family belongs to.
- fig
- draw(renderer: matplotlib.backend_bases.RendererBase) None[source]#
Draw the members visible in the current view.
- Parameters:
- renderer
matplotlib.backend_bases.RendererBase The active renderer.
- renderer