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

API: Polar: allow flipped y/rlims.... #12300

Merged
merged 3 commits into from
Dec 3, 2018

Conversation

jklymak
Copy link
Member

@jklymak jklymak commented Sep 26, 2018

PR Summary

Closes #11202
Closes #10704

Update

Allow non-increasing ylimits:

  • needs doc updates
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()

ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)
ax.plot(np.arange(30), np.arange(30) / 30. + 1)
ax.set_ylim(2, 1)  # out of order, and hence didn't draw properly.

plt.show()

polar

ax.set_rorigin(3.)

polar2

OLD:

This adds a check for set_ylim in polar to make sure they are in order and swap and emit an error if they are not. Because I had to overload axes.set_ylim I changed the argument handling a bit (hopefully correctly).

Fixes a typo in axes/_base.py

import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure(dpi=120)

ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)

ax.set_theta_zero_location('N')
ax.set_theta_direction(-1)  # anti-clockwise

ax.set_ylim(90, -45)  # out of order, and hence didn't draw properly.  
ax.set_yticks(np.arange(-45, 90+0.1, 15))

plt.show()

PR Checklist

  • Has Pytest style unit tests
  • Code is Flake 8 compliant
  • New features are documented, with examples if plot related
  • Documentation is sphinx and numpydoc compliant
  • Added an entry to doc/users/next_whats_new/ if major new feature (follow instructions in README.rst there)
  • Documented in doc/api/api_changes.rst if API changed in a backward-incompatible way

@WeatherGod
Copy link
Member

Devil's advocate here: (just about) everywhere else we are able to flip the order of the limits (particular favorite is pressure-as-height). Why shouldn't we be allowed to do something similar for polar plots?

@jklymak
Copy link
Member Author

jklymak commented Sep 26, 2018

@WeatherGod Fine with me! But someone has to rewrite it so it works, which it does not right now...

Copy link
Member

@timhoffm timhoffm left a comment

Choose a reason for hiding this comment

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

If we plan to support an inverted axis at some point in the future, we should break with an error in that case for now.

While we can always move from an error to new functionality, going from auto-switching to inverted axis support would be a breaking change.

More philosophically, I feel that auto-switching may be too clever anyway. We can expect users to give the range in the correct order. If they don't, they either do it intentionally, because they expect a certain effect, or it's actually mistake, which might have other effects and go unnoticed because we corrected it for the plot ("but the plot looked correct").

So, I'm -1 on auto-switching.

@jklymak
Copy link
Member Author

jklymak commented Sep 26, 2018

That makes sense. I’m fine w an error and if someone wants to implement inverted axes they can do so in future

@ImportanceOfBeingErnest
Copy link
Member

I agree with @timhoffm here. You don't need to implement axis inversion here, but if you allow arbitrary order now, it'll be hard to allow for axis inversion via set_*lim in the future.

The error might point towards a possible workaround for now. For the r axis: "To mimic an inverted r-axis plot data.max()-data and set the ticklabels accordingly.". For theta axis: "Use set_theta_direction instead."

@jklymak
Copy link
Member Author

jklymak commented Sep 27, 2018

Changed to a ValueError and changed the doc string to reflect thats what will happen.

I don't know that we need to point out all the possible work arounds in an error message - they tend to be hard to describe in a line or two. But if you had something pithy, that'd be fine.

Copy link
Member

@timhoffm timhoffm left a comment

Choose a reason for hiding this comment

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

I'm fine now with the functionality. Just some style issues.

lib/matplotlib/projections/polar.py Outdated Show resolved Hide resolved
def set_rlim(self, *args, **kwargs):
def set_rlim(self, bottom=None, top=None, emit=True, auto=False, **kwargs):
"""
See `~.polar.PolarAxes.set_ylim`
Copy link
Member

Choose a reason for hiding this comment

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

See ~.polar.PolarAxes.set_ylim. Additionally, you can pass rmin/rmax in place of ymin/ymax.

Copy link
Member Author

Choose a reason for hiding this comment

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

?? Not following this. We are trying to deprecate rmin, ymin etc. (Well, I don't agree with calling them bottom and top, but...)

Copy link
Member

Choose a reason for hiding this comment

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

Thought to document the current state, even if it's deprecated (well, which should be mentioned then). But since this had no documentation at all so far. It's also ok to keep this a secret.

lib/matplotlib/projections/polar.py Outdated Show resolved Hide resolved
lib/matplotlib/projections/polar.py Outdated Show resolved Hide resolved
@timhoffm timhoffm dismissed their stale review September 27, 2018 06:07

Agreed on raising an error.

@tacaswell tacaswell added this to the v3.1 milestone Sep 27, 2018
@jklymak jklymak changed the title API: flip ylim arguments if not ascending API: Polar: error if ylim args in wrong order.... Sep 27, 2018
timhoffm
timhoffm previously approved these changes Sep 27, 2018
lib/matplotlib/projections/polar.py Outdated Show resolved Hide resolved

right : scalar, optional
The right xlim (default: None, which leaves the right limit
The right xlim (default: ``None``, which leaves the right limit
Copy link
Member

Choose a reason for hiding this comment

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

We don't have a consistent policy for None, True, False so far.

There are all styles present in our docs:

  • plain
  • literal: double backticks
  • italics: starred

Personally, I find double backslashes too cumbersome to type and visually too broad in plain text for there short words. I just use *None*.

The numpydoc and sphinx examples just use plain text.

Just mentioning. Since we currently have no standards, I won't hold this up.

Copy link
Member Author

Choose a reason for hiding this comment

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

Happy to adopt whatever standard folks like the best, or to start a standard! It was plain before, happy to put it back.

Copy link
Member Author

Choose a reason for hiding this comment

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

... and I note I missed about half of them. Switched back to plain text.

@jklymak
Copy link
Member Author

jklymak commented Sep 27, 2018

Added a small test for ValueError....

@jklymak jklymak force-pushed the fix-polar-ylim-order branch 3 times, most recently from 9b195c2 to 24ca248 Compare September 28, 2018 19:12
@jklymak
Copy link
Member Author

jklymak commented Sep 28, 2018

squashed and rebased

@tacaswell
Copy link
Member

It looks like this used to work with inverted axes, but we broke it (likely inadvertently) in the polar refactor. I think we should look into fixing it before we make it raise.

Copy link
Member

@tacaswell tacaswell left a comment

Choose a reason for hiding this comment

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

We should at least investigate why this broke.

Auto-inverting the axis direction for rectilinear plots (for better or worse), I don't see why radial plots should be different.

@jklymak
Copy link
Member Author

jklymak commented Sep 29, 2018

Fair enough. I didn’t know it used to work. I’ll clowe and we can reopen if we decide we can’t fix it.

@jklymak jklymak closed this Sep 29, 2018
@WeatherGod
Copy link
Member

WeatherGod commented Sep 29, 2018 via email

@jklymak
Copy link
Member Author

jklymak commented Sep 29, 2018

I don’t see any reason inverting the axis is difficult mathematically. I just assumed it wasn’t working on purpose.

@tacaswell tacaswell reopened this Sep 29, 2018
@tacaswell tacaswell dismissed their stale review September 29, 2018 21:40

I was confused by SO answers, I am not sure this ever worked anymore...

@tacaswell
Copy link
Member

I just tested all they way back to 1.5 and this never actually worked (but silently kept going).

Sorry for the noise 🐑 .

@jklymak
Copy link
Member Author

jklymak commented Sep 29, 2018

No problem - but OTOH, I don't actually see why this can't work. Marking WIP while I take a quick look...

@jklymak
Copy link
Member Author

jklymak commented Sep 30, 2018

OK, this seems to work fine...

import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()

ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)
ax.plot(np.arange(30), np.arange(30) / 30. + 1)
ax.set_ylim(2, 1)  # out of order, and hence didn't draw properly.

plt.show()

polar

ax.set_rorigin(3.)

polar2

@jklymak jklymak dismissed timhoffm’s stale review September 30, 2018 18:31

Clearing because the PR is now not just raising an error

@jklymak jklymak changed the title API: Polar: error if ylim args in wrong order.... API: Polar: allow flipped y/rlims.... Sep 30, 2018
@jklymak
Copy link
Member Author

jklymak commented Nov 11, 2018

Rebased....

Copy link
Member

@QuLogic QuLogic left a comment

Choose a reason for hiding this comment

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

Only some minor comments for now.

lib/matplotlib/projections/polar.py Show resolved Hide resolved
lib/matplotlib/projections/polar.py Show resolved Hide resolved
@QuLogic
Copy link
Member

QuLogic commented Nov 20, 2018

Something funny happens if you flip the radial limits after a draw:

#!/usr/bin/env python

import numpy as np
import matplotlib.pyplot as plt

fig, (ax0, ax1, ax2) = plt.subplots(1, 3, subplot_kw=dict(polar=True))

ax0.plot([0, 1], [-1, 1])
ax0.scatter([0, 1], [-1, 1])

ax0.set_rmin(-1.5)
ax0.set_rmax(1.5)
ax0.set_title('Forward')

ax1.plot([0, 1], [-1, 1])
ax1.scatter([0, 1], [-1, 1])

ax1.set_rmin(1.5)
ax1.set_rmax(-1.5)
ax1.set_title('Backward')

ax2.plot([0, 1], [-1, 1])
ax2.scatter([0, 1], [-1, 1])

ax2.set_rmin(-1.5)
ax2.set_rmax(1.5)
ax2.set_title('Backward with draw')
fig.canvas.draw()
ax2.set_rmin(1.5)
ax2.set_rmax(-1.5)

plt.show()

figure_1

@jklymak
Copy link
Member Author

jklymak commented Nov 20, 2018

@QuLogic Agreed, but that predates this PR, and is a different issue. On master:

import numpy as np
import matplotlib.pyplot as plt

fig, (ax0,  ax2) = plt.subplots(1, 2, subplot_kw=dict(polar=True))

ax0.plot([0, 1], [-1, 1])
ax0.scatter([0, 1], [-1, 1])

ax0.set_rmin(-1.5)
ax0.set_rmax(1.5)
ax0.set_title('Forward')


ax2.plot([0, 1], [-1, 1])
ax2.scatter([0, 1], [-1, 1])

ax2.set_rmin(-1.5)
ax2.set_rmax(1.5)
ax2.set_title('draw; change rlims')
fig.canvas.draw()
ax2.set_rmin(0)
ax2.set_rmax(1.5)

plt.show()

fliplim

Copy link
Member

@QuLogic QuLogic left a comment

Choose a reason for hiding this comment

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

Some typos to fix, but otherwise good to go.

lib/matplotlib/projections/polar.py Outdated Show resolved Hide resolved
lib/matplotlib/projections/polar.py Outdated Show resolved Hide resolved
lib/matplotlib/projections/polar.py Outdated Show resolved Hide resolved
@jklymak
Copy link
Member Author

jklymak commented Dec 3, 2018

Typos fixed - this has two approvals and could be merged if anyone has a minute...

@QuLogic QuLogic merged commit 61dec52 into matplotlib:master Dec 3, 2018
@jklymak jklymak deleted the fix-polar-ylim-order branch December 3, 2018 21:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants