2
2
import types
3
3
4
4
import numpy as np
5
+ import warnings
5
6
6
7
from matplotlib .axes import Axes
7
8
import matplotlib .axis as maxis
@@ -57,7 +58,8 @@ def transform_non_affine(self, tr):
57
58
t += self ._axis .get_theta_offset ()
58
59
59
60
if self ._use_rmin and self ._axis is not None :
60
- r = r - self ._axis .get_rorigin ()
61
+ r = (r - self ._axis .get_rorigin ()) * self ._axis .get_rsign ()
62
+
61
63
mask = r < 0
62
64
x [:] = np .where (mask , np .nan , r * np .cos (t ))
63
65
y [:] = np .where (mask , np .nan , r * np .sin (t ))
@@ -161,6 +163,7 @@ def transform_non_affine(self, xy):
161
163
162
164
if self ._use_rmin and self ._axis is not None :
163
165
r += self ._axis .get_rorigin ()
166
+ r *= self ._axis .get_rsign ()
164
167
165
168
return np .concatenate ((theta , r ), 1 )
166
169
transform_non_affine .__doc__ = \
@@ -421,10 +424,9 @@ def __call__(self):
421
424
# Ensure previous behaviour with full circle non-annular views.
422
425
if self ._axes :
423
426
if _is_full_circle_rad (* self ._axes .viewLim .intervalx ):
424
- rorigin = self ._axes .get_rorigin ()
427
+ rorigin = self ._axes .get_rorigin () * self . _axes . get_rsign ()
425
428
if self ._axes .get_rmin () <= rorigin :
426
429
show_all = False
427
-
428
430
if show_all :
429
431
return self .base ()
430
432
else :
@@ -444,7 +446,7 @@ def refresh(self):
444
446
445
447
def view_limits (self , vmin , vmax ):
446
448
vmin , vmax = self .base .view_limits (vmin , vmax )
447
- return mtransforms .nonsingular (min ( 0 , vmin ) , vmax )
449
+ return mtransforms .nonsingular (vmin , vmax )
448
450
449
451
450
452
class _ThetaShift (mtransforms .ScaledTranslation ):
@@ -767,7 +769,6 @@ def __str__(self):
767
769
def get_points (self ):
768
770
if self ._invalid :
769
771
points = self ._viewLim .get_points ().copy ()
770
-
771
772
# Scale angular limits to work with Wedge.
772
773
points [:, 0 ] *= 180 / np .pi
773
774
if points [0 , 0 ] > points [1 , 0 ]:
@@ -992,8 +993,8 @@ def draw(self, *args, **kwargs):
992
993
thetamin , thetamax = np .rad2deg (self ._realViewLim .intervalx )
993
994
if thetamin > thetamax :
994
995
thetamin , thetamax = thetamax , thetamin
995
- rmin , rmax = self ._realViewLim .intervaly - self .get_rorigin ()
996
-
996
+ rmin , rmax = (( self ._realViewLim .intervaly - self .get_rorigin ()) *
997
+ self . get_rsign ())
997
998
if isinstance (self .patch , mpatches .Wedge ):
998
999
# Backwards-compatibility: Any subclassed Axes might override the
999
1000
# patch to not be the Wedge that PolarAxes uses.
@@ -1160,12 +1161,87 @@ def set_rorigin(self, rorigin):
1160
1161
def get_rorigin (self ):
1161
1162
return self ._originViewLim .y0
1162
1163
1163
- def set_rlim (self , * args , ** kwargs ):
1164
+ def get_rsign (self ):
1165
+ return np .sign (self ._originViewLim .y1 - self ._originViewLim .y0 )
1166
+
1167
+ def set_rlim (self , bottom = None , top = None , emit = True , auto = False , ** kwargs ):
1168
+ """
1169
+ See `~.polar.PolarAxes.set_ylim`.
1170
+ """
1164
1171
if 'rmin' in kwargs :
1165
- kwargs ['ymin' ] = kwargs .pop ('rmin' )
1172
+ if bottom is None :
1173
+ bottom = kwargs .pop ('rmin' )
1174
+ else :
1175
+ raise ValueError ('Cannot supply both positional "bottom"'
1176
+ 'argument and kwarg "rmin"' )
1166
1177
if 'rmax' in kwargs :
1167
- kwargs ['ymax' ] = kwargs .pop ('rmax' )
1168
- return self .set_ylim (* args , ** kwargs )
1178
+ if top is None :
1179
+ top = kwargs .pop ('rmax' )
1180
+ else :
1181
+ raise ValueError ('Cannot supply both positional "top"'
1182
+ 'argument and kwarg "rmax"' )
1183
+ return self .set_ylim (bottom = bottom , top = top , emit = emit , auto = auto ,
1184
+ ** kwargs )
1185
+
1186
+ def set_ylim (self , bottom = None , top = None , emit = True , auto = False ,
1187
+ * , ymin = None , ymax = None ):
1188
+ """
1189
+ Set the data limits for the radial axis.
1190
+
1191
+ Parameters
1192
+ ----------
1193
+ bottom : scalar, optional
1194
+ The bottom limit (default: None, which leaves the bottom
1195
+ limit unchanged).
1196
+ The bottom and top ylims may be passed as the tuple
1197
+ (*bottom*, *top*) as the first positional argument (or as
1198
+ the *bottom* keyword argument).
1199
+
1200
+ top : scalar, optional
1201
+ The top limit (default: None, which leaves the top limit
1202
+ unchanged).
1203
+
1204
+ emit : bool, optional
1205
+ Whether to notify observers of limit change (default: True).
1206
+
1207
+ auto : bool or None, optional
1208
+ Whether to turn on autoscaling of the y-axis. True turns on,
1209
+ False turns off (default action), None leaves unchanged.
1210
+
1211
+ ymin, ymax : scalar, optional
1212
+ These arguments are deprecated and will be removed in a future
1213
+ version. They are equivalent to *bottom* and *top* respectively,
1214
+ and it is an error to pass both *ymin* and *bottom* or
1215
+ *ymax* and *top*.
1216
+
1217
+ Returns
1218
+ -------
1219
+ ylimits : tuple
1220
+ Returns the new y-axis limits as (*bottom*, *top*).
1221
+
1222
+ Notes
1223
+ -----
1224
+ The *bottom* value must be less than the *top* value, or a
1225
+ ValueError is raised.
1226
+ """
1227
+
1228
+ if ymin is not None :
1229
+ if bottom is not None :
1230
+ raise ValueError ('Cannot supply both positional "bottom" '
1231
+ 'argument and kwarg "ymin"' )
1232
+ else :
1233
+ bottom = ymin
1234
+ if ymax is not None :
1235
+ if top is not None :
1236
+ raise ValueError ('Cannot supply both positional "top" '
1237
+ 'argument and kwarg "ymax"' )
1238
+ else :
1239
+ top = ymax
1240
+ if top is None and len (bottom ) == 2 :
1241
+ top = bottom [1 ]
1242
+ bottom = bottom [0 ]
1243
+
1244
+ return super ().set_ylim (bottom = bottom , top = top , emit = emit , auto = auto )
1169
1245
1170
1246
def get_rlabel_position (self ):
1171
1247
"""
0 commit comments