tephpy.plotting.axes ==================== .. py:module:: tephpy.plotting.axes .. autoapi-nested-parse:: The tephigram matplotlib projection. ``TephigramAxes`` (registered as the ``"tephigram"`` projection) uses the native rotated x-y plane as its data space, with the temperature/theta mapping exposed as an invertible matplotlib transform and the five background isopleth families drawn by default as zoom-aware artists (spec §3.2). Side-of-axes layout contract (spec §10 item 7): panels beside the diagram are appended with ``mpl_toolkits.axes_grid1``'s axes divider, which tracks the equal-aspect box height — right side, inside-out: the wind-barb gutter, then the indices panel. One divider is created per axes, cached, and shared by every side-panel method; ``_relayout_side_panels`` rebuilds the divider's horizontal stack and reassigns every locator whenever a panel appears, so the inside-out order holds regardless of the order the panel methods are called in (spec §3.2). .. !! processed by numpydoc !! Classes ------- .. autoapisummary:: tephpy.plotting.axes.TephigramTransform tephpy.plotting.axes.TephigramInvertedTransform tephpy.plotting.axes.TephigramAxes Module Contents --------------- .. py:class:: TephigramTransform(shorthand_name=None) Bases: :py:obj:`matplotlib.transforms.Transform` Map ``(temperature, theta)`` pairs to tephigram ``(x, y)`` pairs. A thin, invertible matplotlib wrapper over :func:`tephpy.transforms.xy_from_temperature_theta`; operates on ``(N, 2)`` arrays in diagram-native units (degrees Celsius). .. !! processed by numpydoc !! .. py:attribute:: input_dims :value: 2 The number of input dimensions of this transform. Must be overridden (with integers) in the subclass. .. !! processed by numpydoc !! .. py:attribute:: output_dims :value: 2 The number of output dimensions of this transform. Must be overridden (with integers) in the subclass. .. !! processed by numpydoc !! .. py:attribute:: is_separable :value: False True if this transform is separable in the x- and y- dimensions. .. !! processed by numpydoc !! .. py:attribute:: has_inverse :value: True True if this transform has a corresponding inverse transform. .. !! processed by numpydoc !! .. py:method:: transform_non_affine(values: numpy.typing.ArrayLike) -> numpy.typing.NDArray[numpy.float64] Transform (temperature, theta) pairs to (x, y). :Parameters: **values** : :obj:`ArrayLike ` Array-like of shape ``(N, 2)`` or length ``2``: temperature, theta in degrees Celsius. :Returns: :obj:`numpy.ndarray` The tephigram x, y coordinates (the axes' data space), with the input's dimensionality preserved: shape ``(N, 2)`` for ``(N, 2)`` input, shape ``(2,)`` for length-2 input. .. !! processed by numpydoc !! .. py:method:: inverted() -> TephigramInvertedTransform Return the inverse (x, y) -> (temperature, theta) transform. :Returns: :obj:`TephigramInvertedTransform` The inverse transform. .. !! processed by numpydoc !! .. py:class:: TephigramInvertedTransform(shorthand_name=None) Bases: :py:obj:`matplotlib.transforms.Transform` Map tephigram ``(x, y)`` pairs back to ``(temperature, theta)``. .. !! processed by numpydoc !! .. py:attribute:: input_dims :value: 2 The number of input dimensions of this transform. Must be overridden (with integers) in the subclass. .. !! processed by numpydoc !! .. py:attribute:: output_dims :value: 2 The number of output dimensions of this transform. Must be overridden (with integers) in the subclass. .. !! processed by numpydoc !! .. py:attribute:: is_separable :value: False True if this transform is separable in the x- and y- dimensions. .. !! processed by numpydoc !! .. py:attribute:: has_inverse :value: True True if this transform has a corresponding inverse transform. .. !! processed by numpydoc !! .. py:method:: transform_non_affine(values: numpy.typing.ArrayLike) -> numpy.typing.NDArray[numpy.float64] Transform (x, y) pairs to (temperature, theta). :Parameters: **values** : :obj:`ArrayLike ` Array-like of shape ``(N, 2)`` or length ``2``: tephigram x, y coordinates (the axes' data space). :Returns: :obj:`numpy.ndarray` Temperature, theta in degrees Celsius, with the input's dimensionality preserved: shape ``(N, 2)`` for ``(N, 2)`` input, shape ``(2,)`` for length-2 input. .. !! processed by numpydoc !! .. py:method:: inverted() -> TephigramTransform Return the forward (temperature, theta) -> (x, y) transform. :Returns: :obj:`TephigramTransform` The forward transform. .. !! processed by numpydoc !! .. py:class:: TephigramAxes(fig, *args, facecolor=None, frameon=True, sharex=None, sharey=None, label='', xscale=None, yscale=None, box_aspect=None, forward_navigation_events='auto', **kwargs) Bases: :py:obj:`matplotlib.axes.Axes` Matplotlib axes for the ``"tephigram"`` projection. The data space is the native rotated x-y plane (dimensionless), with equal aspect so the isotherm/dry-adiabat grid stays exactly perpendicular on screen. The five background isopleth families are drawn by default as zoom-aware artists and reconfigured through the accessor methods (:meth:`isotherms`, :meth:`isobars`, :meth:`dry_adiabats`, :meth:`moist_adiabats`, :meth:`mixing_ratios`). The temperature/theta mapping is exposed as :attr:`tephigram_transform`; artists plot in (temperature, theta) space via ``transform=ax.tephigram_transform + ax.transData``. Native x/y ticks carry no meteorological meaning and are hidden until a family claims an edge for its labels — ``labels=("bottom", "left")`` turns them into that family's scale (spec §3.2). .. !! processed by numpydoc !! .. py:attribute:: name :value: 'tephigram' .. py:attribute:: tephigram_transform :type: TephigramTransform .. py:method:: clear() -> None Reset the axes to the tephigram projection defaults. Matplotlib calls this during ``Axes.__init__`` and on user ``ax.clear()``; both paths recreate the projection-owned state: the tephigram transform, equal aspect, hidden native axes, the five background isopleth families, any edges they claim for their labels, and the default extent (``tephpy.config`` diagram extent, else ``DEFAULT_EXTENT``). Side panels — the barb gutter and the indices panel — are removed with the diagram they annotated, except when the figure is clearing itself: it removes every axes anyway, and it is iterating a snapshot this one must not delete from. :Raises: :obj:`TypeError` If ``tephpy.config`` gives one diagram edge to two families, or names an unknown label placement, or carries a malformed family ``emphasis`` — a non-mapping, a member value that will not convert to float, a style that is not a mapping, or an unknown style key (spec §3.2). :obj:`ValueError` If a ``tephpy.config`` family ``emphasis`` keys a member value that is not finite, or gives a ``linewidth`` that is not positive and finite, or an ``alpha`` outside ``[0, 1]``, or a family ``interval`` is not positive and finite. .. !! processed by numpydoc !! .. py:method:: set_extent(extent: tuple[tuple[float, float], tuple[float, float]]) -> None Fix the view from ((pressure, temperature), ...) corners. The cartopy-style idiom for directly comparable figures (spec §3.2): the two corners are mapped through the tephigram transforms to x/y limits, and autoscaling is disabled so later overlays never drift the window. :Parameters: **extent** : :class:`python:tuple` ``((pressure, temperature), (pressure, temperature))`` bottom-left and top-right corners in hPa / degrees Celsius. :Raises: :obj:`ValueError` If a corner is unphysical (non-positive pressure) or the corners are degenerate. .. !! processed by numpydoc !! .. py:method:: format_coord(x: float, y: float) -> str Report diagram-meaningful values for the cursor position (spec §3.2). The navigation toolbar's readout: the data-space cursor position inverts to (temperature, theta), pressure derives via Poisson's equation, and the configured fields render in listed order, e.g. ``850 hPa, -4.2 °C, θ 8.6 °C``. Fields resolve as instance assignment > ``tephpy.config`` > ``_constants``: assigning ``ax.format_coord = fn`` (stock matplotlib) shadows this method entirely, and ``config.cursor.fields`` is read live on every call, so a ``config.context(cursor={"fields": ...})`` override applies to existing axes for its duration (spec §3.5). Fields whose value is undefined at the point are omitted from the readout. :Parameters: **x** : :class:`python:float` Cursor x in tephigram data space. **y** : :class:`python:float` Cursor y in tephigram data space. :Returns: :class:`python:str` The formatted readout, or ``""`` when the position is unphysical (e.g. left of the -273.15 °C isotherm). :Raises: :obj:`TypeError` If ``config.cursor.fields`` is a bare string rather than a tuple of field names, or names an unknown field. .. !! processed by numpydoc !! .. py:method:: plot_profile(pressure: tephpy.calc.Profile, *, label: str | None = None, **kwargs: Any) -> matplotlib.lines.Line2D plot_profile(pressure: object, temperature: object, *, units: collections.abc.Mapping[str, str] | None = None, label: str | None = None, **kwargs: Any) -> matplotlib.lines.Line2D Plot one profile of temperature against pressure (spec §3.2). Both arrays are pint quantities — or bare arrays with the ``units=`` mapping (spec §5) — converted to diagram-native units and plotted through the tephigram transform machinery. Matplotlib keywords pass through untouched, and out-of-domain values (pressure <= 0 hPa) propagate NaN, breaking the line (spec §3.1). The same signature also accepts a ``calc.Profile`` (e.g. the return of ``calc.parcel_path``) as its only positional argument; dispatch is duck-typed on the ``Profile`` shape — `temperature` omitted and ``pressure``/``temperature``/``lcl_pressure`` attributes present. Label precedence in that form: `label` argument > ``profile.label`` > no entry. In both forms no style defaults are set — this is the low-level primitive (spec §4 styles parcel paths explicitly at the call site). :Parameters: **pressure** : :obj:`pint.Quantity`, :obj:`ArrayLike `, or :obj:`Profile ` Level pressures, or the profile to plot. **temperature** : :obj:`pint.Quantity` or :obj:`ArrayLike `, optional Level temperatures; omitted in the ``Profile`` form. **units** : mapping of :class:`python:str` to :class:`python:str`, optional Unit strings for bare arrays, keyed by argument name, e.g. ``units={"pressure": "hPa", "temperature": "degC"}``; not accepted in the ``Profile`` form. **label** : :class:`python:str`, optional Legend label for the line. **\*\*kwargs** : :obj:`Any` Passed through to :meth:`matplotlib.axes.Axes.plot`. :Returns: :obj:`matplotlib.lines.Line2D` The profile line. :Raises: :obj:`TephpyUnitsError ` For unit-less bare arrays, ambiguous or unparsable units, or the wrong dimensionality. :obj:`TypeError` For wrong argument combinations: a ``Profile`` together with `temperature` or ``units=``, or `temperature` omitted when the sole argument is not ``Profile``-shaped (a bare pressure array, or a ``Sounding`` passed by mistake). .. !! processed by numpydoc !! .. py:method:: plot_sounding(snd: tephpy.sounding.Sounding, *, label: str | None = None, **kwargs: Any) -> tuple[matplotlib.lines.Line2D, matplotlib.lines.Line2D | None] Plot a sounding's temperature and dewpoint profiles (spec §3.2). Temperature and dewpoint-when-present draw as two profile lines in the conventional colours (temperature red, dewpoint green), with one legend entry per sounding attached to the temperature line. Label precedence: `label` argument > ``snd.label`` > no entry. Matplotlib keywords pass through to both lines, overriding the convention defaults; legends stay stock matplotlib — call ``ax.legend()``. :Parameters: **snd** : :obj:`Sounding ` The sounding to plot. **label** : :class:`python:str`, optional Legend label override. **\*\*kwargs** : :obj:`Any` Passed through to :meth:`matplotlib.axes.Axes.plot` for both lines. :Returns: :class:`python:tuple` of :obj:`matplotlib.lines.Line2D` ``(temperature_line, dewpoint_line)``; the dewpoint line is ``None`` when the sounding has no dewpoint. .. !! processed by numpydoc !! .. py:method:: shade_cape(snd: tephpy.sounding.Sounding, parcel: tephpy.calc.Profile, **kwargs: Any) -> matplotlib.patches.PathPatch | None Shade the CAPE area between the sounding and a parcel path. The positive-buoyancy region between the environment temperature and the parcel path, bounded as :func:`metpy.calc.cape_cin` integrates — from the LFC to the EL, to the profile top when the parcel is still buoyant there — so the shading matches the annotated numbers (spec §3.2). Drawn as one compound-path patch; interrupted regions become multiple polygons in the same patch. :Parameters: **snd** : :obj:`Sounding ` The environment sounding. **parcel** : :obj:`Profile ` The parcel path, e.g. from ``calc.parcel_path``. **\*\*kwargs** : :obj:`Any` Passed through to :class:`matplotlib.patches.PathPatch`, overriding the ``_constants`` conventions. :Returns: :obj:`matplotlib.patches.PathPatch` or :data:`python:None` The shaded patch, or ``None`` for zero area — 0 is an answer, not an error (spec §6). .. !! processed by numpydoc !! .. py:method:: shade_cin(snd: tephpy.sounding.Sounding, parcel: tephpy.calc.Profile, **kwargs: Any) -> matplotlib.patches.PathPatch | None Shade the CIN area between the sounding and a parcel path. The negative-buoyancy region between the environment temperature and the parcel path, bounded as :func:`metpy.calc.cape_cin` integrates — from the parcel start to the LFC — so the shading matches the annotated numbers (spec §3.2). Drawn as one compound-path patch; with no LFC there is no CIN region. :Parameters: **snd** : :obj:`Sounding ` The environment sounding. **parcel** : :obj:`Profile ` The parcel path, e.g. from ``calc.parcel_path``. **\*\*kwargs** : :obj:`Any` Passed through to :class:`matplotlib.patches.PathPatch`, overriding the ``_constants`` conventions. :Returns: :obj:`matplotlib.patches.PathPatch` or :data:`python:None` The shaded patch, or ``None`` for zero area — 0 is an answer, not an error (spec §6). .. !! processed by numpydoc !! .. py:method:: edge_axis(edge: str) -> matplotlib.axis.Axis Return the matplotlib axis drawing one diagram edge's ticks. The uniform handle on all four edges (spec §3.2), keyed by the same names the ``labels`` option takes. Bottom and left are the axes' own ``xaxis``/``yaxis``; top and right belong to a secondary axes that has no other public handle. tephpy stamps its tick conventions on an edge axis once, when that axis is created, so everything stock matplotlib offers is the caller's from the claim onwards — e.g. ``ax.edge_axis("top").set_tick_params(labelsize=12)``, or ``set_label_text("")`` to keep the ticks and drop the axis title. The only thing tephpy changes afterwards is the tick colour, and only when the owning family's own colour or alpha changes, or another family takes the edge. :Parameters: **edge** : :class:`python:str` The edge, one of ``EDGES``. :Returns: :obj:`matplotlib.axis.Axis` The axis drawing that edge's ticks. :Raises: :obj:`TypeError` If `edge` is not one of ``EDGES``. :obj:`ValueError` If no family labels that edge. An unclaimed edge renders nothing to style — bottom and left are hidden, and top and right have no axis yet — and probing one must not build a secondary axes nothing is using. .. !! processed by numpydoc !! .. py:method:: plot_barbs(snd: tephpy.sounding.Sounding, *, x: float | None = None, minimum_separation: float | None = None, **kwargs: Any) -> tephpy.plotting.barbs.BarbStaff Plot the sounding's wind barbs on the gutter staff (spec §3.2). The barbs draw on a right-hand gutter appended with the shared divider, each level at the y where its isobar meets the diagram's right edge (the printed-form staff convention), thinned per draw to a minimum vertical separation — zooming in reveals more levels. Met Office symbology: flag 50 kt, full barb 10 kt, half barb 5 kt, speeds rounded to 5 kt bins; calm levels render as matplotlib's small circle. Each call draws one staff: overlay soundings by calling again with another `x`, `minimum_separation`, and colour. :Parameters: **snd** : :obj:`Sounding ` The sounding to plot; must carry wind. **x** : :class:`python:float`, optional The staff position as a fraction across the gutter (default ``BARB_STAFF_POSITION``). **minimum_separation** : :class:`python:float`, optional The minimum vertical separation between drawn barbs, in points (default ``BARB_MIN_SEPARATION``) — a longer ``length=`` glyph wants a wider separation. **\*\*kwargs** : :obj:`Any` Passed through to :class:`matplotlib.quiver.Barbs`, over the ``_constants`` conventions (increments, rounding, length). :Returns: :obj:`BarbStaff ` The zoom-aware staff artist; its ``barbs`` property is the underlying matplotlib collection. :Raises: :obj:`MissingDataError ` If the sounding has no wind (spec §6). .. !! processed by numpydoc !! .. py:method:: annotate_indices(indices: tephpy.calc.SoundingIndices) -> matplotlib.axes.Axes Display derived parameters in a panel beside the diagram. The first consumer of the side-of-axes contract (spec §3.2): the panel is appended with the ``axes_grid1`` divider, one formatted line per ``SoundingIndices`` field, NaN rendered as an em dash. Calling it again updates the panel in place rather than stacking a second one, and the side-panel layout is rebuilt inside-out (barb gutter, then this panel) whichever order the panel methods are called in (spec §3.2). :Parameters: **indices** : :obj:`SoundingIndices ` The derived parameters, e.g. from ``calc.indices``. :Returns: :obj:`matplotlib.axes.Axes` The panel axes, for restyling. .. !! processed by numpydoc !! .. py:method:: isotherms(*, values: collections.abc.Iterable[float] | None = None, interval: float | None = None, color: str | None = None, linewidth: float | None = None, alpha: float | None = None, labels: bool | str | tuple[str, Ellipsis] | None = None, emphasis: collections.abc.Mapping[float, collections.abc.Mapping[str, object]] | None = None, visible: bool | None = None) -> tephpy.plotting.isopleths.IsoplethFamily Return (and optionally reconfigure) the isotherm family. With no arguments this returns the family artist unchanged; any keyword given reconfigures it first (spec §3.2). Values are in degrees Celsius. :Parameters: **values** : :term:`python:iterable` of :class:`python:float`, optional Explicit member temperatures; disables the zoom ladder. **interval** : :class:`python:float`, optional Member interval; disables the zoom ladder. **color** : :class:`python:str`, optional Line and label colour. **linewidth** : :class:`python:float`, optional Line width in points. **alpha** : :class:`python:float`, optional Line and label alpha. **labels** : :ref:`bool ` or :class:`python:str` or :class:`python:tuple` of :class:`python:str`, optional Where member values are labelled: ``True`` (every member inline — the default), ``False`` (none), or the diagram edge names ``"bottom"``, ``"top"``, ``"left"`` and ``"right"``, singly or as a tuple. Listed edges label the members that reach them; every member left over is labelled inline. One family per edge. An edge crowded by closely spaced members is thinned with ``interval=``; edge labelling never drops a member's label itself. **emphasis** : mapping of :class:`python:float` to mapping, optional Members to distinguish, keyed by member value in degrees Celsius. Each value is a mapping of style overrides — ``color``, ``linewidth``, ``linestyle``, ``alpha`` — and an omitted key falls back to the family's own style, so ``{0.0: {}}`` draws that member at ``EMPHASIS_LINEWIDTH`` in the family's own colour. An emphasised member is always drawn, whatever the zoom ladder would select, so a value the interval never lands on still appears. An empty mapping emphasises nothing. **visible** : :ref:`bool `, optional Whether the family is drawn. :Returns: :obj:`IsoplethFamily ` The isotherm family artist. :Raises: :obj:`TypeError` If ``labels`` names an unknown placement, ``emphasis`` is malformed, or an edge another family already claims. :obj:`ValueError` If an ``emphasis`` member value is not finite, a ``linewidth`` is not positive and finite, an ``alpha`` falls outside ``[0, 1]``, or ``interval`` is not positive and finite. .. !! processed by numpydoc !! .. py:method:: isobars(*, values: collections.abc.Iterable[float] | None = None, interval: float | None = None, color: str | None = None, linewidth: float | None = None, alpha: float | None = None, labels: bool | str | tuple[str, Ellipsis] | None = None, emphasis: collections.abc.Mapping[float, collections.abc.Mapping[str, object]] | None = None, visible: bool | None = None) -> tephpy.plotting.isopleths.IsoplethFamily Return (and optionally reconfigure) the isobar family. With no arguments this returns the family artist unchanged; any keyword given reconfigures it first (spec §3.2). Values are in hPa. :Parameters: **values** : :term:`python:iterable` of :class:`python:float`, optional Explicit member pressures; disables the zoom ladder. **interval** : :class:`python:float`, optional Member interval; disables the zoom ladder. **color** : :class:`python:str`, optional Line and label colour. **linewidth** : :class:`python:float`, optional Line width in points. **alpha** : :class:`python:float`, optional Line and label alpha. **labels** : :ref:`bool ` or :class:`python:str` or :class:`python:tuple` of :class:`python:str`, optional Where member values are labelled: ``True`` (every member inline — the default), ``False`` (none), or the diagram edge names ``"bottom"``, ``"top"``, ``"left"`` and ``"right"``, singly or as a tuple. Listed edges label the members that reach them; every member left over is labelled inline. One family per edge. An edge crowded by closely spaced members is thinned with ``interval=``; edge labelling never drops a member's label itself. **emphasis** : mapping of :class:`python:float` to mapping, optional Members to distinguish, keyed by member value in hPa. Each value is a mapping of style overrides — ``color``, ``linewidth``, ``linestyle``, ``alpha`` — and an omitted key falls back to the family's own style, so ``{500.0: {}}`` draws that member at ``EMPHASIS_LINEWIDTH`` in the family's own colour. An emphasised member is always drawn, whatever the zoom ladder would select, so a value the interval never lands on still appears. An empty mapping emphasises nothing. **visible** : :ref:`bool `, optional Whether the family is drawn. :Returns: :obj:`IsoplethFamily ` The isobar family artist. :Raises: :obj:`TypeError` If ``labels`` names an unknown placement, ``emphasis`` is malformed, or an edge another family already claims. :obj:`ValueError` If an ``emphasis`` member value is not finite, a ``linewidth`` is not positive and finite, an ``alpha`` falls outside ``[0, 1]``, or ``interval`` is not positive and finite. .. !! processed by numpydoc !! .. py:method:: dry_adiabats(*, values: collections.abc.Iterable[float] | None = None, interval: float | None = None, color: str | None = None, linewidth: float | None = None, alpha: float | None = None, labels: bool | str | tuple[str, Ellipsis] | None = None, emphasis: collections.abc.Mapping[float, collections.abc.Mapping[str, object]] | None = None, visible: bool | None = None) -> tephpy.plotting.isopleths.IsoplethFamily Return (and optionally reconfigure) the dry-adiabat family. With no arguments this returns the family artist unchanged; any keyword given reconfigures it first (spec §3.2). Values are potential temperatures in degrees Celsius. :Parameters: **values** : :term:`python:iterable` of :class:`python:float`, optional Explicit member potential temperatures; disables the zoom ladder. **interval** : :class:`python:float`, optional Member interval; disables the zoom ladder. **color** : :class:`python:str`, optional Line and label colour. **linewidth** : :class:`python:float`, optional Line width in points. **alpha** : :class:`python:float`, optional Line and label alpha. **labels** : :ref:`bool ` or :class:`python:str` or :class:`python:tuple` of :class:`python:str`, optional Where member values are labelled: ``True`` (every member inline — the default), ``False`` (none), or the diagram edge names ``"bottom"``, ``"top"``, ``"left"`` and ``"right"``, singly or as a tuple. Listed edges label the members that reach them; every member left over is labelled inline. One family per edge. An edge crowded by closely spaced members is thinned with ``interval=``; edge labelling never drops a member's label itself. **emphasis** : mapping of :class:`python:float` to mapping, optional Members to distinguish, keyed by member value in degrees Celsius. Each value is a mapping of style overrides — ``color``, ``linewidth``, ``linestyle``, ``alpha`` — and an omitted key falls back to the family's own style, so ``{0.0: {}}`` draws that member at ``EMPHASIS_LINEWIDTH`` in the family's own colour. An emphasised member is always drawn, whatever the zoom ladder would select, so a value the interval never lands on still appears. An empty mapping emphasises nothing. **visible** : :ref:`bool `, optional Whether the family is drawn. :Returns: :obj:`IsoplethFamily ` The dry-adiabat family artist. :Raises: :obj:`TypeError` If ``labels`` names an unknown placement, ``emphasis`` is malformed, or an edge another family already claims. :obj:`ValueError` If an ``emphasis`` member value is not finite, a ``linewidth`` is not positive and finite, an ``alpha`` falls outside ``[0, 1]``, or ``interval`` is not positive and finite. .. !! processed by numpydoc !! .. py:method:: moist_adiabats(*, values: collections.abc.Iterable[float] | None = None, interval: float | None = None, truncation: float | None = None, color: str | None = None, linewidth: float | None = None, alpha: float | None = None, labels: bool | str | tuple[str, Ellipsis] | None = None, emphasis: collections.abc.Mapping[float, collections.abc.Mapping[str, object]] | None = None, visible: bool | None = None) -> tephpy.plotting.isopleths.IsoplethFamily Return (and optionally reconfigure) the moist-adiabat family. With no arguments this returns the family artist unchanged; any keyword given reconfigures it first (spec §3.2). Values are wet-bulb potential temperatures in degrees Celsius. :Parameters: **values** : :term:`python:iterable` of :class:`python:float`, optional Explicit member wet-bulb potential temperatures; disables the zoom ladder. **interval** : :class:`python:float`, optional Member interval; disables the zoom ladder. **truncation** : :class:`python:float`, optional Temperature (°C) below which the curves are truncated. **color** : :class:`python:str`, optional Line and label colour. **linewidth** : :class:`python:float`, optional Line width in points. **alpha** : :class:`python:float`, optional Line and label alpha. **labels** : :ref:`bool ` or :class:`python:str` or :class:`python:tuple` of :class:`python:str`, optional Where member values are labelled: ``True`` (every member inline — the default), ``False`` (none), or the diagram edge names ``"bottom"``, ``"top"``, ``"left"`` and ``"right"``, singly or as a tuple. Listed edges label the members that reach them; every member left over is labelled inline. One family per edge. An edge crowded by closely spaced members is thinned with ``interval=``; edge labelling never drops a member's label itself. **emphasis** : mapping of :class:`python:float` to mapping, optional Members to distinguish, keyed by member value in degrees Celsius. Each value is a mapping of style overrides — ``color``, ``linewidth``, ``linestyle``, ``alpha`` — and an omitted key falls back to the family's own style, so ``{0.0: {}}`` draws that member at ``EMPHASIS_LINEWIDTH`` in the family's own colour. An emphasised member is always drawn, whatever the zoom ladder would select, so a value the interval never lands on still appears. An empty mapping emphasises nothing. **visible** : :ref:`bool `, optional Whether the family is drawn. :Returns: :obj:`IsoplethFamily ` The moist-adiabat family artist. :Raises: :obj:`TypeError` If ``labels`` names an unknown placement, ``emphasis`` is malformed, or an edge another family already claims. :obj:`ValueError` If an ``emphasis`` member value is not finite, a ``linewidth`` is not positive and finite, an ``alpha`` falls outside ``[0, 1]``, or ``interval`` is not positive and finite. .. !! processed by numpydoc !! .. py:method:: mixing_ratios(*, values: collections.abc.Iterable[float] | None = None, color: str | None = None, linewidth: float | None = None, alpha: float | None = None, labels: bool | str | tuple[str, Ellipsis] | None = None, emphasis: collections.abc.Mapping[float, collections.abc.Mapping[str, object]] | None = None, visible: bool | None = None) -> tephpy.plotting.isopleths.IsoplethFamily Return (and optionally reconfigure) the mixing-ratio family. With no arguments this returns the family artist unchanged; any keyword given reconfigures it first (spec §3.2). Values are humidity mixing ratios in g/kg; this family has no ``interval`` (its members come from the ``MIXING_RATIO_VALUES`` ladder). :Parameters: **values** : :term:`python:iterable` of :class:`python:float`, optional Explicit member mixing ratios; disables the zoom ladder. **color** : :class:`python:str`, optional Line and label colour. **linewidth** : :class:`python:float`, optional Line width in points. **alpha** : :class:`python:float`, optional Line and label alpha. **labels** : :ref:`bool ` or :class:`python:str` or :class:`python:tuple` of :class:`python:str`, optional Where member values are labelled: ``True`` (every member inline — the default), ``False`` (none), or the diagram edge names ``"bottom"``, ``"top"``, ``"left"`` and ``"right"``, singly or as a tuple. Listed edges label the members that reach them; every member left over is labelled inline. One family per edge. An edge crowded by a large member set is thinned with ``values=``; edge labelling never drops a member's label itself. **emphasis** : mapping of :class:`python:float` to mapping, optional Members to distinguish, keyed by member value in g/kg. Each value is a mapping of style overrides — ``color``, ``linewidth``, ``linestyle``, ``alpha`` — and an omitted key falls back to the family's own style, so ``{5.0: {}}`` draws that member at ``EMPHASIS_LINEWIDTH`` in the family's own colour. An emphasised member is always drawn, whatever the zoom ladder would select, so a value the ladder never selects still appears. An empty mapping emphasises nothing. **visible** : :ref:`bool `, optional Whether the family is drawn. :Returns: :obj:`IsoplethFamily ` The mixing-ratio family artist. :Raises: :obj:`TypeError` If ``labels`` names an unknown placement, ``emphasis`` is malformed, or an edge another family already claims. :obj:`ValueError` If an ``emphasis`` member value is not finite, a ``linewidth`` is not positive and finite, or an ``alpha`` falls outside ``[0, 1]``. .. !! processed by numpydoc !!