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

Reorganization of declarative syntax #1879

Merged
merged 1 commit into from Jul 16, 2021

Conversation

kgoebber
Copy link
Collaborator

@kgoebber kgoebber commented May 20, 2021

Description Of Changes

Okay, so try number 2 to get the reorganization, started by @jthielen to allow for a more flexible syntax to add other types of plots (e.g., SkewT, Hovmoller, Line Plots, etc.). This is largely based on the reorganization that @jthielen produced and supplied in the discussion about changes to the declarative syntax.

In future PRs we'll work to add these new plotting abilities, which may then require further, albeit hopefully smaller changes, to the structure to allow for maximum functionality.

@kgoebber kgoebber force-pushed the reorg_declarative branch 2 times, most recently from 09a7257 to 968cb8f Compare May 20, 2021 20:19
@kgoebber kgoebber force-pushed the reorg_declarative branch 2 times, most recently from a655e2b to c47944e Compare June 21, 2021 21:47

return x, y, self.griddata
return (
self.griddata[self.griddata.dims[1]],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this take us back to an era where we depended up on the order of the dimensions? Couldn't we pick one or the other of x and longitude?

Copy link
Collaborator

@jthielen jthielen Jun 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I missed that in jthielen@cfef550. Though I do wonder based on not seeing any transpose/shape handling if xy-ordered data worked before this change? (Or I could just be totally missing something...I haven't worked with xy-ordered data in quite some time.)

However, we definitely can't just pick the physical x dimension coordinate, since this is an x axis only in the plotting sense, data-wise it could be any of MetPy's axis types (or even an arbitary dimension like the index of a cross section). In the case where the two dimensions are MetPy axis types, given that there are six possible dimension pairs (x-y, x-vertical, x-time, y-vertical, y-time, and vertical-time), should we force/assume which of the pair goes on which axis or find a way to leave it up to the user? Or find some compromise in between? And how should we handle arbitrary dimensions?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So in the end, we will always have two dimensional data, and we now have better checks for that with a warning. We could default to the ordering of the data based on our most common current use case (y-x) and build in some sensible choices based on the names of dimensions, but otherwise include an attribute like swap_axes that could be boolean (which defaults to False) to allow a change on the fly.

@kgoebber
Copy link
Collaborator Author

Okay, I have taken a swing at updating the reorganization to align the comments. It doesn't fully address @jthielen points around ordering of dimensions, but at least gets us set up to tackle that more robustly once we go to add our first non-xy (non-latlon) declarative plot. Will need to address the BarbPlot as well to be more robust with choice of dimension, currently set of a y-x plotting order.

src/metpy/plots/declarative.py Outdated Show resolved Hide resolved
src/metpy/plots/declarative.py Show resolved Hide resolved
@kgoebber kgoebber force-pushed the reorg_declarative branch 2 times, most recently from de92050 to b8bb846 Compare June 23, 2021 01:12
@dopplershift dopplershift added this to the 1.1.0 milestone Jun 23, 2021
@kgoebber kgoebber force-pushed the reorg_declarative branch 2 times, most recently from fef74c1 to 04b0880 Compare July 7, 2021 18:40
y = self.griddata.metpy.y

return x, y, self.griddata
if (set(self.griddata.dims) == {'x', 'y'}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason not to do:

try:
    x = self.griddata.metpy.x
    y = self.griddata.metpy.y
except AttributeError:
    x = self.griddata[self.griddata.dims[1]]
    y = self.griddata[self.griddata.dims[0]]

return x, y, self.griddata

This would seem less likely to break anything (i.e. things that have an x/y coordinates without calling them lat/lon or x/y).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code you suggested does work, but again, I think we are attempting to future proof here to make it easier to add different types of plots (and those some elif statements to handle other cases. @jthielen again might offer his own insight on this one too.

Copy link
Collaborator

@jthielen jthielen Jul 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dopplershift We unfortunately can't do that since x and/or y from the accessor may still be present even when we are not in yx (or xy) space (likewise to the previous comment). But, yes, the implementation here is way to likely to break something (I honestly don't know why I even did it this way in the first place).

Like the other case, we'll probably need to leverage a try/except with find_axis_number:

try:
    plot_x_dim = self.griddata.metpy.find_axis_number('x')
    plot_y_dim = self.griddata.metpy.find_axis_number('y')
except ValueError:
    plot_x_dim = 1
    plot_y_dim = 0

return (
    self.griddata[self.griddata.dims[plot_x_dim]],
    self.griddata[self.griddata.dims[plot_y_dim]],
    self.griddata
)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm much happier with the implementation suggested by @jthielen here and below.

Comment on lines 1425 to 1431
x_like = self.griddata[0][self.griddata[0].dims[1]]
y_like = self.griddata[0][self.griddata[0].dims[0]]

if (
x_like.name == self.griddata[0].metpy.find_axis_name('x')
and y_like.name == self.griddata[0].metpy.find_axis_name('y')
):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem right. x_like/y_like is relying on the order, while we then look at finding them by name, but then assume those are the same.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is currently a future proofing set up to be able to plot wind barbs not just on XY planes, but time-height cross sections or regular cross sections. We don't currently have that ability, so that is why the if statement checking for matching of x and y coordinates doesn't have an elif statement at this time. @jthielen might be able to provide more clarity here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this was an attempt at future-proofing for non-map 2D plots. As described in the comment below, this is a conditional check to only carry out the earth/grid relative adjustments if we are in the plane of the plot (i.e., a map rather than a general 2D plot).

However, the confusion is definitely warranted, since this doesn't match the intent...or at the very least, won't work for the desired generalized case. Since find_axis_name only finds dimension coordinate names, as-is this will error out when not in an yx case, since then y and/or x are not there.

The goal is to check that we are in yx space (or technically also xy, but my initial attempt neglected the non-standard dimension order), which gets a bit tricky since we have to use find_axis_name or find_axis_number which enforce dimension coordinates rather than MetPy's coordinate helpers for y and x (which just enforce 0D or 1D coords). So, this may need to change to something like the following

check_earth_relative = False
try:
    plot_x_dim = self.griddata[0].metpy.find_axis_number('x')
    plot_y_dim = self.griddata[0].metpy.find_axis_number('y')
    check_earth_relative = True
except ValueError:
   plot_x_dim = 1
   plot_y_dim = 0

x_like = self.griddata[0][self.griddata[0].dims[plot_x_dim]]
y_like = self.griddata[0][self.griddata[0].dims[plot_y_dim]]

if check_earth_relative:
   ...

@kgoebber
Copy link
Collaborator Author

Okay, I have implemented both changes. Some of this may naturally evolve once we implement the first non-xy, non-map plotting through declarative, but that should all be on the backend and not expose too much tax on ourselves moving forward.

Copy link
Member

@dcamron dcamron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the silent lurking up to this point, but I appreciate this most recent discussion and these last few changes; I think it's ready to get in!

@dcamron dcamron merged commit ee542e0 into Unidata:main Jul 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants