Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Add option for creating inset SkewTs #1708

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions src/metpy/_vendor/matplotlib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Copyright (c) 2019 MetPy Developers.
# Distributed under the terms of the BSD 3-Clause License.
# SPDX-License-Identifier: BSD-3-Clause
"""Vendor core functionality used from matplotlib.

This code has been reproduced from matplotlib 3.3.4 in accord with its license agreement
(reproduced below).

1. This LICENSE AGREEMENT is between the Matplotlib Development Team ("MDT"), and the
Individual or Organization ("Licensee") accessing and otherwise using matplotlib software
in source or binary form and its associated documentation.

2. Subject to the terms and conditions of this License Agreement, MDT hereby grants
Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test,
perform and/or display publicly, prepare derivative works, distribute, and otherwise use
matplotlib 3.3.4 alone or in any derivative version, provided, however, that MDT's License
Agreement and MDT's notice of copyright, i.e., "Copyright (c) 2012-2013 Matplotlib
Development Team; All Rights Reserved" are retained in matplotlib 3.3.4 alone or in any
derivative version prepared by Licensee.

3. In the event Licensee prepares a derivative work that is based on or incorporates
matplotlib 3.3.4 or any part thereof, and wants to make the derivative work available to
others as provided herein, then Licensee hereby agrees to include in any such work a brief
summary of the changes made to matplotlib 3.3.4.

4. MDT is making matplotlib 3.3.4 available to Licensee on an "AS IS" basis. MDT MAKES NO
REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION,
MDT MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB 3.3.4 WILL NOT INFRINGE ANY THIRD
PARTY RIGHTS.

5. MDT SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB 3.3.4 FOR ANY
INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING,
DISTRIBUTING, OR OTHERWISE USING MATPLOTLIB 3.3.4, OR ANY DERIVATIVE THEREOF, EVEN IF
ADVISED OF THE POSSIBILITY THEREOF.

6. This License Agreement will automatically terminate upon a material breach of its terms
and conditions.

7. Nothing in this License Agreement shall be deemed to create any relationship of agency,
partnership, or joint venture between MDT and Licensee. This License Agreement does not
grant permission to use MDT trademarks or trade name in a trademark sense to endorse or
promote products or services of Licensee, or any third party.

8. By copying, installing or otherwise using matplotlib 3.3.4, Licensee agrees to be bound
by the terms and conditions of this License Agreement.
"""
import matplotlib.transforms as mtransforms


class _TransformedBoundsLocator:
"""
Copyright (c) 2012-2013 Matplotlib Development Team; All Rights Reserved

This class is reproduced exactly from matplotlib/axes/_base.py, excluding the
modifications made to this comment.

Axes locator for `.Axes.inset_axes` and similarly positioned axes.
The locator is a callable object used in `.Axes.set_aspect` to compute the
axes location depending on the renderer.
"""

def __init__(self, bounds, transform):
"""
*bounds* (a ``[l, b, w, h]`` rectangle) and *transform* together
specify the position of the inset axes.
"""
self._bounds = bounds
self._transform = transform

Check warning on line 69 in src/metpy/_vendor/matplotlib.py

View check run for this annotation

Codecov / codecov/patch

src/metpy/_vendor/matplotlib.py#L68-L69

Added lines #L68 - L69 were not covered by tests

def __call__(self, ax, renderer):
# Subtracting transSubfigure will typically rely on inverted(),
# freezing the transform; thus, this needs to be delayed until draw
# time as transSubfigure may otherwise change after this is evaluated.
return mtransforms.TransformedBbox(

Check warning on line 75 in src/metpy/_vendor/matplotlib.py

View check run for this annotation

Codecov / codecov/patch

src/metpy/_vendor/matplotlib.py#L75

Added line #L75 was not covered by tests
mtransforms.Bbox.from_bounds(*self._bounds),
self._transform - ax.figure.transSubfigure)
81 changes: 78 additions & 3 deletions src/metpy/plots/skewt.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import numpy as np

from ._util import colored_line
from .._vendor.matplotlib import _TransformedBoundsLocator
from ..calc import dewpoint, dry_lapse, el, lcl, moist_lapse, vapor_pressure
from ..calc.tools import _delete_masked_points
from ..interpolate import interpolate_1d
Expand Down Expand Up @@ -264,7 +265,7 @@

"""

def __init__(self, fig=None, rotation=30, subplot=None, rect=None, aspect=80.5):
def __init__(self, fig=None, rotation=30, subplot=None, rect=None, aspect=80.5, **kwargs):
r"""Create SkewT - logP plots.

Parameters
Expand All @@ -289,6 +290,8 @@
Aspect ratio (i.e. ratio of y-scale to x-scale) to maintain in the plot.
Defaults to 80.5. Passing the string ``'auto'`` tells matplotlib to handle
the aspect ratio automatically (this is not recommended for SkewT).
kwargs
Additional keyword arguments passed when creating the axes.

"""
if fig is None:
Expand All @@ -301,7 +304,7 @@
raise ValueError("Specify only one of `rect' and `subplot', but not both")

elif rect:
self.ax = fig.add_axes(rect, projection='skewx', rotation=rotation)
self.ax = fig.add_axes(rect, projection='skewx', rotation=rotation, **kwargs)

else:
if subplot is not None:
Expand All @@ -313,7 +316,12 @@
else:
subplot = (1, 1, 1)

self.ax = fig.add_subplot(*subplot, projection='skewx', rotation=rotation)
self.ax = fig.add_subplot(
*subplot,
projection='skewx',
rotation=rotation,
**kwargs
)

# Set the yaxis as inverted with log scaling
self.ax.set_yscale('log')
Expand Down Expand Up @@ -342,6 +350,73 @@
if matplotlib.__version__[:3] > '3.1':
self.ax.set_aspect(aspect, adjustable='box')

@classmethod
def inset(cls, ax, bounds, transform=None, zorder=5, rotation=30, aspect=80.5, **kwargs):
r"""Create SkewT - logP plot as an inset.

Parameters
----------
ax : matplotlib.axes.Axes
Source axes on which to place the inset SkewT.
bounds : tuple[float, float, float, float]
Rectangle (left, bottom, width, height) in which to place the axes. This
allows the user to place the axes at an arbitrary point on the figure. See the
``transform`` argument for controlling the coordinate system used in these bounds.
transform : matplotlib.transforms.Transform, optional
Defaults to ``ax.transData``, the coordinate system for the data. Other options
include ``ax.transAxes`` for axes-relative coordinates, ``fig.transFirgure`` for
figure-relative coordinates, or
``ax.get_x_axis_transform()``/``ax.get_y_axis_transform()`` for blended
coordinates (data coordinates on one axis and axes coordinates on the other).
zorder : number, optional
Defaults to 5. Adjust higher or lower to change whether it is above or below data
plotted on the parent axes.
rotation : float or int, optional
Controls the rotation of temperature relative to horizontal. Given
in degrees counterclockwise from x-axis. Defaults to 30 degrees.
aspect : float, int, or 'auto', optional
Aspect ratio (i.e. ratio of y-scale to x-scale) to maintain in the plot.
Defaults to 80.5. Passing the string ``'auto'`` tells matplotlib to handle
the aspect ratio automatically (this is not recommended for SkewT).
kwargs
Additional keyword arguments passed when creating the axes.

Returns
-------
SkewT

"""
if transform is None:
transform = ax.transData

Check warning on line 390 in src/metpy/plots/skewt.py

View check run for this annotation

Codecov / codecov/patch

src/metpy/plots/skewt.py#L389-L390

Added lines #L389 - L390 were not covered by tests

# This segement copied with modification from matplotlib: Copyright (c) 2012-2013
# Matplotlib Development Team; All Rights Reserved. See license agreement in
# _vendor/matplotlib.py. Modified from original to have parent Axes be an argument
# rather than self, create a SkewT object rather than Axes directly, and use Axes from
# that SkewT instance instead of directly created Axes.

# This puts the rectangle into figure-relative coordinates.
inset_locator = _TransformedBoundsLocator(bounds, transform)
bounds = inset_locator(ax, None).bounds

Check warning on line 400 in src/metpy/plots/skewt.py

View check run for this annotation

Codecov / codecov/patch

src/metpy/plots/skewt.py#L399-L400

Added lines #L399 - L400 were not covered by tests

# Create the skewT using the transformed bounds
skew_t = cls(

Check warning on line 403 in src/metpy/plots/skewt.py

View check run for this annotation

Codecov / codecov/patch

src/metpy/plots/skewt.py#L403

Added line #L403 was not covered by tests
ax.figure,
rotation=rotation,
rect=bounds,
aspect=aspect,
zorder=zorder,
**kwargs
)

# this locator lets the axes move if in data coordinates.
# it gets called in `ax.apply_aspect() (of all places)
skew_t.ax.set_axes_locator(inset_locator)

Check warning on line 414 in src/metpy/plots/skewt.py

View check run for this annotation

Codecov / codecov/patch

src/metpy/plots/skewt.py#L414

Added line #L414 was not covered by tests

# End copy

return skew_t

Check warning on line 418 in src/metpy/plots/skewt.py

View check run for this annotation

Codecov / codecov/patch

src/metpy/plots/skewt.py#L418

Added line #L418 was not covered by tests

def plot(self, pressure, t, *args, **kwargs):
r"""Plot data.

Expand Down