Skip to content

Conversation

@DPeterK
Copy link
Member

@DPeterK DPeterK commented May 23, 2013

A cf attribute that can be set on vertical coordinates is 'positive', which indicates the direction in which they should be plotted to retain visual meaning. Thus positive = up indicates 0 should be plotted at the bottom of the y-axis as standard while positive = down indicates that 0 should be plotted at the top of the y-axis. This is beneficial when plotting phenomena such as air pressure or depth, both of which intuitively increase downward.

Iris plotting methods did not handle this coordinate however, which is what this PR changes. To accomplish this, I modified netcdf.py to allow the positive attribute to be added to coords on building a cube from an nc file. I then modified plot.py to pick up this attribute such that if it was found on a coordinate to be plotted then the y-axis is inverted.

I modified the tests to pass: adding a test to test_netcdf.py for the presence of positive on a dimcoord known to have it set; adding a test class to test_plot.py to test that positive = up/down are being plotted correctly; changing the cml files affected by the presence of a new attribute within a dimcoord.

@esc24
Copy link
Member

esc24 commented May 24, 2013

I'm in favour of this in principle. However, I'm not sure about the logic that's been used. For example, if I'm plotting a 'down' coordinate on the horizontal axis do I want to invert the y-axis? I do not believe so. Do I want to invert the x-axis? I'm not sure.

@DPeterK
Copy link
Member Author

DPeterK commented May 24, 2013

This is true. It might well be worth restricting it to 'only invert the y-axis if the down coordinate is being plotted on the y-axis'. However if ever a y-like coordinate needed to be plotted inverted on the x-axis this suggestion would clearly prevent that. I'll investigate whether such a y-like coordinate would ever need to be plotted on the x-axis.

@pelson
Copy link
Member

pelson commented May 24, 2013

Do I want to invert the x-axis?

I think so. I also think you would want the positive attribute to apply to both the x and y if your x and y coordinates both define a positive attribute...

@DPeterK
Copy link
Member Author

DPeterK commented Jun 5, 2013

I asked the scientist whose request originally prompted this work about whether the x-axis would ever need to be inverted and his view is that it shouldn't.

Further, according to the CF conventions doc, section 1.3; "Other vertical coordinates must use the attribute positive which determines whether the direction of increasing coordinate value is up or down."
And, from section 4.3: "A vertical coordinate will be identifiable by units of pressure, or the presence of the positive attribute with a value of up or down (case insensitive)."
As such, I think this should only apply to the y-axis when a y-like (vertical) coordinate as defined above is being plotted on it.

Of course if it is needed there is nothing to stop the x-axis being inverted manually, which I think might prove a more appropriate way to go forward with this.

Copy link
Member

Choose a reason for hiding this comment

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

This is a little strict. Perhaps test:

self.assertEquals(cube.coord('height').attributes['positive'], 'up')

@pp-mo
Copy link
Member

pp-mo commented Jun 7, 2013

Do I want to invert the x-axis?

I think so. I also think you would want the positive attribute to apply to both the x and y if your x and y coordinates both define a positive attribute...

I think I agree with @dkillick on this one -- not to invert a X axis.
I looked into this, and as far as I could see, CF and COARDS only specifiy a 'positive' attribute for vertical coordinates.
So, it seems to me, the intent of that is to encode the desired vertical arrangement of the coordinate axis
-- i.e. to make both "height-like" and "depth-like" levels display nicely.
So I would only apply this to a Y axis: If you are displaying something like depth/height on a horizontal axis, I'd expect it revert to a simple ascending-value order
-- e.g. a horizontal "depth" axis displays as 1, 5, 10, 50, 100, not 100, 50, 10, 5, 1 (which would be the sequence for vertical orientation).

( Sorry if this repeats, I wrote before seeing @dkillick latest ! )

Copy link
Member

Choose a reason for hiding this comment

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

You said that the CF spec states that this is case insensitive, perhaps you could change this to:
cube.attributes['positive'] = 'DOWN' and make the necessary changes to plot.py.

@esc24
Copy link
Member

esc24 commented Jun 11, 2013

You seem to have a couple of test images that correspond to an earlier commit:
lib/iris/tests/results/visual_tests/test_plot.TestAttributePositive.test_positive_down.0.png
lib/iris/tests/results/visual_tests/test_plot.TestAttributePositive.test_positive_up.0.png
I think you can safely remove these.

@ajdawson
Copy link
Member

I'm confused about a cube having a positive attribute, does this make sense? Looking at your test cases for 1D plots, the positive attribute causes the temperature axis to be inverted, when surely the intention is that the depth coordinate should be reversed? I would have thought you should still be checking for a positive attribute on the coordinate not the cube. Please clarify.

Also, wouldn't it make more sense to plot depth on the y-axis for these examples? It concerns me that the y-axis is reversed when it probably is not intended to be.

@DPeterK
Copy link
Member Author

DPeterK commented Jun 27, 2013

Thanks for your comments @ajdawson and apologies for the radio silence at my end - I'm working on another project currently that's proving quite time-intensive!

In terms of your comments, firstly the cube does not under normal circumstances gain a positive attribute. Only a y-like coordinate will gain that attribute, unless, as in the case of this test, the attribute is forced. Second, the inversion of the temperature axis in this case is actually the appropriate behaviour because clearly in the 1D case the data plotted on the y-axis is actually the data within the dramatically constrained cube. This is then being set to be plotted inverted, which is indeed what is happening. Further, I chose the specific data here because the x-axis data has positive=down so it also (admittedly implicitly) tests that the x-axis is not inverted in this case. Hopefully this answers your concerns.

@ajdawson
Copy link
Member

In terms of your comments, firstly the cube does not under normal circumstances gain a positive attribute. Only a y-like coordinate will gain that attribute, unless, as in the case of this test, the attribute is forced.

OK that makes things clearer. I just think the test images are a little confusing. Is it actually possible to make a 1D plot of the same cube but with depth on the y-axis in iris?

@ajdawson
Copy link
Member

Is it actually possible to make a 1D plot of the same cube but with depth on the y-axis in iris?

Perhaps this can't be done using iris.plot? I didn't find anything in a quick scan of the docs that suggests you can even do this, I guess that is a good reason why you didn't! Anyone know any different?

@DPeterK
Copy link
Member Author

DPeterK commented Jun 27, 2013

I agree they could be better, but unfortunately I was a little restricted as to what data I could use as test data, hence the decision as laid out above.

So iris.plot expects a 1D cube, plotting the values of the single dimension along the x-axis and cube.data on the y-axis, which makes logical sense when considered against the convention generally for making an x-y line graph. Thus, to make a 1D Iris plot with depth on the y-axis would require constraining a cube of depth data to a single dimension (e.g. depth vs time). My problem was that I could not find a single cube containing that sort of data, let alone one containing data in the public domain! This also sort of forced the test to use the data it did.

@ajdawson
Copy link
Member

I guess my point is that if this is supposed to apply to vertical coordinates only (seems fine) then there should be a way to plot a depth profile, so exactly the same data you have used but with depth on the y-axis. If this really is not possible with iris.plot, which it seems not to be, then it should be fixed (not in this PR) as this is a perfectly reasonable thing to do. In light of this your test plots seem very reasonable!

@ajdawson
Copy link
Member

OK I've thought about this some more and here is where I stand:

  • the implementation for 2D plots is fine
  • for 1D plots it doesn't really work

The goal of the PR is to support inversion for vertical coordinates. Since one cannot make a plot of a 1D cube with the coordinate on the y-axis anayway, it does not make sense to support inverting the data axis by having a positive attribute on the cube. As you said, under normal circumstances the cube will not gain a positive attribute, so what is the functionality catering for?

I propose that the 2D plotting aspects of this PR remain as they are, but the 1D aspects should be removed until such time that iris is capable of plotting a 1D cube with the coordinate on the y-axis. When this happens it will make sense to invert the coordinate that will be on the y-axis.

@rhattersley
Copy link
Member

I propose that the 2D plotting aspects of this PR remain as they are, but the 1D aspects should be removed until such time that iris is capable of plotting a 1D cube with the coordinate on the y-axis. When this happens it will make sense to invert the coordinate that will be on the y-axis.

👍 Sounds good.

@ajdawson
Copy link
Member

@dkillick since #593 is now merged it should be possible for this to be extended to 1D plots in a way that makes sense.

@ajdawson
Copy link
Member

@dkillick a further thought occurred to me: what happens if the user makes two plots on the same axes, both of which are of variables that have a vertical coordinate with a positive='down' attribute?

For example, if I have two cubes which represent say zonal velocity in the ocean and an anomalous zonal velocity, both of which have a vertical coordinate 'depth' with the positive='down' attribute. I want to plot line contours of the anomaly over the full field:

fill = contourf(velocity, coords=['latitude', 'depth'])
line = contour(velocity_anomaly, coords=['latitude', 'depth'])

The first call will correctly invert the y-axis, but won't the second also detect the vertical coordinate should be inverted and end up undoing the inversion?

@DPeterK
Copy link
Member Author

DPeterK commented Jul 30, 2013

Good call @ajdawson! I just had a play with a simple matplotlib plot and you're quite right - as ax.invert_yaxis() is something of a toggle, each time it is called it just inverts what it already has. Fortuitously there is a similar function: ax.yaxis_inverted(), which is a boolean test of whether the y-axis is inverted.

Thus I propose that I will add a test to the code that does the to check whether the y-axis is already inverted. Something like if not ax.yaxis_inverted() should do nicely.

@ajdawson
Copy link
Member

Fortuitously there is a similar function

Jolly good then! 😄

Copy link
Member

Choose a reason for hiding this comment

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

Does this cube have a vertical coordinate with a positive=down attribute?

Edit: sorry of course it does, I'm doing something wrong at my end!

@ajdawson
Copy link
Member

ajdawson commented Aug 7, 2013

The 1d positive=down test image isn't correct, it should have depth on the y-axis according to the test case but the image has temperature on the y-axis and it is inverted... Can you check this please.

@DPeterK
Copy link
Member Author

DPeterK commented Aug 19, 2013

Oh, so it is... now sorted. I didn't notice because the tests did not fail...

@ajdawson
Copy link
Member

Oh, so it is... now sorted

I don't see any new commits or other changes to the branch...

@DPeterK
Copy link
Member Author

DPeterK commented Aug 19, 2013

Indeed not, I was just sorting out the potential lower case issue highlighted above. Commit to follow soon...

@ajdawson
Copy link
Member

Sorry I thought you meant you had already done it.

@esc24
Copy link
Member

esc24 commented Aug 19, 2013

@dkillick - you've got a PEP8 failure.

lib/iris/plot.py Outdated
Copy link
Member

Choose a reason for hiding this comment

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

Missing full stop.

@ajdawson
Copy link
Member

FYI @dkillick just adding commits to a PR doesn't seem to generate a notification, so add a comment if you want people to know that you have made changes and are ready for re-review.

I'd like to have a quick play with it tomorrow to double check in a real-world setting so to speak, but it looks ready for merge.

@ghost ghost assigned ajdawson Aug 21, 2013
@DPeterK
Copy link
Member Author

DPeterK commented Aug 22, 2013

Interesting, I wasn't aware of that. Thanks for letting me know @ajdawson!

@ajdawson
Copy link
Member

@dkillick - can you check if this breaks any of the example tests. I think it should cause the first plot in the atlantic_profiles example to be upside down (because it manually inverts the axis). However, I'm having strange issues testing this on my machine (see comments in #671, the test doesn't fail even when the y-axis is inverted). It would be good to see what result you get...

@DPeterK
Copy link
Member Author

DPeterK commented Aug 29, 2013

@ajdawson I just ran the example tests on my machine here and they all passed, so I had a look running the code manually and the first plot is indeed plotting so that the y-axis has 0 at the bottom again. This must be because when plot runs it will invert the y-axis which is then inverted again by the y-axis invert command later on in the example code. So I commented that line and re-ran the tests... no failure. Seems I'm seeing the same behaviour as you are.

@ajdawson
Copy link
Member

@dkillick - OK that is sort of what I expected. I think this PR should remove the manual inversion line from that example so that the gallery will build correctly, lets not worry about the test for now as I think it is a much deeper issue. Perhaps you could also add a short comment in the example to say the axis will be automatically inverted due to its positive=down attribute? After that I think this one is good to go. Are you able to work on it today to get it in before the 1.5.x branch is cut? It would be good to get this in.

@esc24
Copy link
Member

esc24 commented Aug 29, 2013

Those pesky thresholds 😉. @ajdawson is right - drop the manual inversion and let's get this merged.

@ajdawson
Copy link
Member

@dkillick - looks good. Can you squash these commits into one please. There were some travis fails that look related to recently merged PRs. I'm not exactly sure how these errors came about but could you also rebase onto the current master while you are at it to try and make these go away?

@esc24
Copy link
Member

esc24 commented Aug 29, 2013

I think those failures may be my fault.

@DPeterK
Copy link
Member Author

DPeterK commented Aug 29, 2013

Rebased, squashed, pushed. Just awaiting Travis results now...

@ajdawson
Copy link
Member

Not having much luck with Travis on this PR! I'm not sure what caused that error, perhaps just a Travis glitch, I'll try and restart it.

@esc24
Copy link
Member

esc24 commented Aug 29, 2013

I just did a local merge and ran all three sets of tests. Everything passes and the depth axis looks good in the example so 👍.

ajdawson added a commit that referenced this pull request Aug 29, 2013
y-axis inversion for vertical coords
@ajdawson ajdawson merged commit c9b5700 into SciTools:master Aug 29, 2013
@ajdawson
Copy link
Member

Thanks @dkillick, good work.

@DPeterK
Copy link
Member Author

DPeterK commented Aug 29, 2013

Got there at last 😄

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.

6 participants