Unidata / MetPy

MetPy is a collection of tools in Python for reading, visualizing and performing calculations with weather data.
https://unidata.github.io/MetPy/
BSD 3-Clause "New" or "Revised" License
1.21k stars 408 forks source link

Place Skew-T's On Figure Using Data Coordinates #1706

Open jsillin opened 3 years ago

jsillin commented 3 years ago

I recently have been using MetPy's excellent SkewT plotting tool to create plots overlaying a bunch of skew-ts over a region to easily assess the spatial variability of thermodynamic and moisture profiles: gfs_hrly_pytpe_reg_sound_14_2021-02-14_1200Z

Currently, the part of the SkewT plotting line that allows placement of the SkewT axes on the bigger figure uses figure-relative coordinates [0,1]

skew = SkewT(fig=fig,rect=(0.75,0.7,.15,.1)) This gets tricky when doing a whole bunch of these plots because I want to tie the location of the SkewT axes on the bigger figure to a physically-meaningful location (the lat/lon coordinates from which I am pulling the sounding data).

I was wondering if there would be a way to add an option for setting this location similar to Matplotlib's ax.text method which takes lon,lat as the first two arguments to set the position of text on an axis that has lat/lon coordinates.

Maybe this could be a kwarg added onto the rect method where if you say latlon=True, your first two arguments to rect can be a lat/lon for placing the skewT plot.

jthielen commented 3 years ago

I think the best way to do this would be supporting Axes.inset_axes with an existing axes in the SkewT constructor rather than the current two options of creating a new figure or using Figure.add_axes. This would allow the bounds to be specified in the data coordinates using transform=ax.transData, which, while a bit more work for this particular use case, better generalizes to other applications. We would have to be cautious though, as matplotlib's documentation states "This method is experimental as of 3.0, and the API may change." Thoughts @dopplershift?

However, that doesn't preclude also including more helpers for these kinds of "diagram overlay" plots for SkewTs and hodographs. I'm a big fan of these kinds of plots by you and @nixoncameronj, and would love to see a well-tested, openly-released implementation in MetPy or another MetPy-adjacent package.

dopplershift commented 3 years ago

Ugh, I forgot SkewT doesn't allow you to pass in an Axes because it has to specify the "projection" at axes creation time so that we control all the right pieces. The entirety of Axes.inset_axes is:

        if transform is None:
            transform = self.transAxes
        kwargs.setdefault('label', 'inset_axes')

        # This puts the rectangle into figure-relative coordinates.
        inset_locator = _make_inset_locator(bounds, transform, self)
        bb = inset_locator(None, None)

        inset_ax = Axes(self.figure, bb.bounds, zorder=zorder, **kwargs)
        # this locator lets the axes move if in data coordinates.
        # it gets called in `ax.apply_aspect() (of all places)
        inset_ax.set_axes_locator(inset_locator)

        self.add_child_axes(inset_ax)

        return inset_ax

I wonder if we could do a SkewT.inset() as an alternate initializer (i.e. classmethod) and have that do just like inset_axes, passing the rect to the normal __init__.

Like @jthielen said, In general @jsillin we very much want to help facilitate these kinds of plots in MetPy, I think they're super cool and interesting.

jsillin commented 3 years ago

Thanks @dopplershift! I will admit that talk of initializers and classmethods is still a little over my head, but I'm excited to see what y'all can come up with as a solution :) I would love to publish this code and possibly add it to the example catalogue for others to use and tinker with and learn from, but it needs some serious cleaning up haha.

Thanks again for giving this some thought! Really appreciate it

jthielen commented 3 years ago

See https://github.com/Unidata/MetPy/pull/1708 for a first pass at implementing @dopplershift's suggestion above.