8000 API: Polar: allow flipped y/rlims.... by jklymak · Pull Request #12300 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

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

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

Merged
merged 3 commits into from
Dec 3, 2018
Merged
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
12 changes: 6 additions & 6 deletions lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3122,8 +3122,8 @@ def set_xlim(self, left=None, right=None, emit=True, auto=False,
limit unchanged.

The left and right xlims may be passed as the tuple
(`left`, `right`) as the first positional argument (or as
the `left` keyword argument).
(*left*, *right*) as the first positional argument (or as
the *left* keyword argument).

right : scalar, optional
The right xlim in data coordinates. Passing *None* leaves the
Expand Down Expand Up @@ -3169,7 +3169,7 @@ def set_xlim(self, left=None, right=None, emit=True, auto=False,
>>> set_xlim(right=right_lim)

Limits may be passed in reverse order to flip the direction of
the x-axis. For example, suppose ``x`` represents the number of
the x-axis. For example, suppose *x* represents the number of
years before present. The x-axis limits might be set like the
following so 5000 years ago is on the left of the plot and the
present is on the right.
Expand Down Expand Up @@ -3510,15 +3510,15 @@ def set_ylim(self, bottom=None, top=None, emit=True, auto=False,
limit unchanged.

The bottom and top ylims may be passed as the tuple
(`bottom`, `top`) as the first positional argument (or as
the `bottom` keyword argument).
(*bottom*, *top*) as the first positional argument (or as
the *bottom* keyword argument).

top : scalar, optional
The top ylim in data coordinates. Passing *None* leaves the
limit unchanged.

emit : bool, optional
Whether to notify observers of limit change (default: True).
Whether to notify observers of limit change (default: ``True``).

auto : bool or None, optional
Whether to turn on autoscaling of the y-axis. *True* turns on,
Expand Down
97 changes: 86 additions & 11 deletions lib/matplotlib/projections/polar.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import types

import numpy as np
import warnings

from matplotlib.axes import Axes
import matplotlib.axis as maxis
Expand Down Expand Up @@ -57,7 +58,8 @@ def transform_non_affine(self, tr):
t += self._axis.get_theta_offset()

if self._use_rmin and self._axis is not None:
r = r - self._axis.get_rorigin()
r = (r - self._axis.get_rorigin()) * self._axis.get_rsign()

mask = r < 0
x[:] = np.where(mask, np.nan, r * np.cos(t))
y[:] = np.where(mask, np.nan, r * np.sin(t))
Expand Down Expand Up @@ -161,6 +163,7 @@ def transform_non_affine(self, xy):

if self._use_rmin and self._axis is not None:
r += self._axis.get_rorigin()
r *= self._axis.get_rsign()

return np.concatenate((theta, r), 1)
transform_non_affine.__doc__ = \
Expand Down Expand Up @@ -421,10 +424,9 @@ def __call__(self):
# Ensure previous behaviour with full circle non-annular views.
if self._axes:
if _is_full_circle_rad(*self._axes.viewLim.intervalx):
rorigin = self._axes.get_rorigin()
rorigin = self._axes.get_rorigin() * self._axes.get_rsign()
if self._axes.get_rmin() <= rorigin:
show_all = False

if show_all:
return self.base()
else:
Expand All @@ -444,7 +446,10 @@ def refresh(self):

def view_limits(self, vmin, vmax):
vmin, vmax = self.base.view_limits(vmin, vmax)
return mtransforms.nonsingular(min(0, vmin), vmax)
if vmax > vmin:
# this allows inverted r/y-lims
vmin = min(0, vmin)
return mtransforms.nonsingular(vmin, vmax)


class _ThetaShift(mtransforms.ScaledTranslation):
Expand Down Expand Up @@ -767,7 +772,6 @@ def __str__(self):
def get_points(self):
if self._invalid:
points = self._viewLim.get_points().copy()

# Scale angular limits to work with Wedge.
points[:, 0] *= 180 / np.pi
if points[0, 0] > points[1, 0]:
Expand Down Expand Up @@ -992,8 +996,8 @@ def draw(self, *args, **kwargs):
thetamin, thetamax = np.rad2deg(self._realViewLim.intervalx)
if thetamin > thetamax:
thetamin, thetamax = thetamax, thetamin
rmin, rmax = self._realViewLim.intervaly - self.get_rorigin()

rmin, rmax = ((self._realViewLim.intervaly - self.get_rorigin()) *
self.get_rsign())
if isinstance(self.patch, mpatches.Wedge):
# Backwards-compatibility: Any subclassed Axes might override the
# patch to not be the Wedge that PolarAxes uses.
Expand Down Expand Up @@ -1160,12 +1164,83 @@ def set_rorigin(self, rorigin):
def get_rorigin(self):
return self._originViewLim.y0

def set_rlim(self, *args, **kwargs):
def get_rsign(self):
return np.sign(self._originViewLim.y1 - self._originViewLim.y0)

def set_rlim(self, bottom=None, top=None, emit=True, auto=False, **kwargs):
"""
See `~.polar.PolarAxes.set_ylim`.
"""
if 'rmin' in kwargs:
kwargs['ymin'] = kwargs.pop('rmin')
if bottom is None:
bottom = kwargs.pop('rmin')
else:
raise ValueError('Cannot supply both positional "bottom"'
'argument and kwarg "rmin"')
if 'rmax' in kwargs:
kwargs['ymax'] = kwargs.pop('rmax')
return self.set_ylim(*args, **kwargs)
if top is None:
top = kwargs.pop('rmax')
else:
raise ValueError('Cannot supply both positional "top"'
'argument and kwarg "rmax"')
return self.set_ylim(bottom=bottom, top=top, emit=emit, auto=auto,
**kwargs)

def set_ylim(self, bottom=None, top=None, emit=True, auto=False,
*, ymin=None, ymax=None):
"""
Set the data limits for the radial axis.

Parameters
----------
bottom : scalar, optional
The bottom limit (default: None, which leaves the bottom
limit unchanged).
The bottom and top ylims may be passed as the tuple
(*bottom*, *top*) as the first positional argument (or as
the *bottom* keyword argument).

top : scalar, optional
The top limit (default: None, which leaves the top limit
unchanged).

emit : bool, optional
Whether to notify observers of limit change (default: True).

auto : bool or None, optional
Whether to turn on autoscaling of the y-axis. True turns on,
False turns off (default action), None leaves unchanged.

ymin, ymax : scalar, optional
These arguments are deprecated and will be removed in a future
version. They are equivalent to *bottom* and *top* respectively,
and it is an error to pass both *ymin* and *bottom* or
*ymax* and *top*.

Returns
-------
ylimits : tuple
Returns the new y-axis limits as (*bottom*, *top*).

"""

if ymin is not None:
if bottom is not None:
raise ValueError('Cannot supply both positional "bottom" '
'argument and kwarg "ymin"')
else:
bottom = ymin
if ymax is not None:
if top is not None:
raise ValueError('Cannot supply both positional "top" '
'argument and kwarg "ymax"')
else:
top = ymax
if top is None and len(bottom) == 2:
top = bottom[1]
bottom = bottom[0]

return super().set_ylim(bottom=bottom, top=top, emit=emit, auto=auto)

def get_rlabel_position(self):
"""
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,23 @@ def test_polar_rorigin():
ax.set_rorigin(0.0)


@image_comparison(baseline_images=['polar_invertedylim'], style='default',
extensions=['png'])
def test_polar_invertedylim():
fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)
ax.set_ylim(2, 0)


@image_comparison(baseline_images=['polar_invertedylim_rorigin'],
style='default', extensions=['png'])
def test_polar_invertedylim_rorigin():
fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)
ax.set_ylim(2, 0)
ax.set_rorigin(3)


@image_comparison(baseline_images=['polar_theta_position'], style='default')
def test_polar_theta_position():
r = np.arange(0, 3.0, 0.01)
Expand Down
0