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 ))
@@ -168,6 +170,7 @@ def transform_non_affine(self, xy):
168
170
169
171
if self ._use_rmin and self ._axis is not None :
170
172
r += self ._axis .get_rorigin ()
173
+ r *= self ._axis .get_rsign ()
171
174
172
175
return np .concatenate ((theta , r ), 1 )
173
176
transform_non_affine .__doc__ = \
@@ -431,10 +434,9 @@ def __call__(self):
431
434
# Ensure previous behaviour with full circle non-annular views.
432
435
if self ._axes :
433
436
if _is_full_circle_rad (* self ._axes .viewLim .intervalx ):
434
- rorigin = self ._axes .get_rorigin ()
437
+ rorigin = self ._axes .get_rorigin () * self . _axes . get_rsign ()
435
438
if self ._axes .get_rmin () <= rorigin :
436
439
show_all = False
437
-
438
440
if show_all :
439
441
return self .base ()
440
442
else :
@@ -454,7 +456,7 @@ def refresh(self):
454
456
455
457
def view_limits (self , vmin , vmax ):
456
458
vmin , vmax = self .base .view_limits (vmin , vmax )
457
- return mtransforms .nonsingular (min ( 0 , vmin ) , vmax )
459
+ return mtransforms .nonsingular (vmin , vmax )
458
460
459
461
460
462
class _ThetaShift (mtransforms .ScaledTranslation ):
@@ -789,7 +791,6 @@ def __str__(self):
789
791
def get_points (self ):
790
792
if self ._invalid :
791
793
points = self ._viewLim .get_points ().copy ()
792
-
793
794
# Scale angular limits to work with Wedge.
794
795
points [:, 0 ] *= 180 / np .pi
795
796
if points [0 , 0 ] > points [1 , 0 ]:
@@ -1014,8 +1015,8 @@ def draw(self, *args, **kwargs):
1014
1015
thetamin , thetamax = np .rad2deg (self ._realViewLim .intervalx )
1015
1016
if thetamin > thetamax :
1016
1017
thetamin , thetamax = thetamax , thetamin
1017
- rmin , rmax = self ._realViewLim .intervaly - self .get_rorigin ()
1018
-
1018
+ rmin , rmax = (( self ._realViewLim .intervaly - self .get_rorigin ()) *
1019
+ self . get_rsign ())
1019
1020
if isinstance (self .patch , mpatches .Wedge ):
1020
1021
# Backwards-compatibility: Any subclassed Axes might override the
1021
1022
# patch to not be the Wedge that PolarAxes uses.
@@ -1182,12 +1183,87 @@ def set_rorigin(self, rorigin):
1182
1183
def get_rorigin (self ):
1183
1184
return self ._originViewLim .y0
1184
1185
1185
- def set_rlim (self , * args , ** kwargs ):
1186
+ def get_rsign (self ):
1187
+ return np .sign (self ._originViewLim .y1 - self ._originViewLim .y0 )
1188
+
1189
+ def set_rlim (self , bottom = None , top = None , emit = True , auto = False , ** kwargs ):
1190
+ """
1191
+ See `~.polar.PolarAxes.set_ylim`.
1192
+ """
1186
1193
if 'rmin' in kwargs :
1187
- kwargs ['ymin' ] = kwargs .pop ('rmin' )
1194
+ if bottom is None :
1195
+ bottom = kwargs .pop ('rmin' )
1196
+ else :
1197
+ raise ValueError ('Cannot supply both positional "bottom"'
1198
+ 'argument and kwarg "rmin"' )
1188
1199
if 'rmax' in kwargs :
1189
- kwargs ['ymax' ] = kwargs .pop ('rmax' )
1190
- return self .set_ylim (* args , ** kwargs )
1200
+ if top is None :
1201
+ top = kwargs .pop ('rmax' )
1202
+ else :
1203
+ raise ValueError ('Cannot supply both positional "top"'
1204
+ 'argument and kwarg "rmax"' )
1205
+ return self .set_ylim (bottom = bottom , top = top , emit = emit , auto = auto ,
1206
+ ** kwargs )
1207
+
1208
+ def set_ylim (self , bottom = None , top = None , emit = True , auto = False ,
1209
+ * , ymin = None , ymax = None ):
1210
+ """
1211
+ Set the data limits for the radial-axis.
1212
+
1213
+ Parameters
1214
+ ----------
1215
+ bottom : scalar, optional
1216
+ The bottom limit (default: None, which leaves the bottom
1217
+ limit unchanged).
1218
+ The bottom and top ylims may be passed as the tuple
1219
+ (*bottom*, *top*) as the first positional argument (or as
1220
+ the *bottom* keyword argument).
1221
+
1222
+ top : scalar, optional
1223
+ The top ylim (default: None, which leaves the top limit
1224
+ unchanged).
1225
+
1226
+ emit : bool, optional
1227
+ Whether to notify observers of limit change (default: True).
1228
+
1229
+ auto : bool or None, optional
1230
+ Whether to turn on autoscaling of the y-axis. True turns on,
1231
+ False turns off (default action), None leaves unchanged.
1232
+
1233
+ ymin, ymax : scalar, optional
1234
+ These arguments are deprecated and will be removed in a future
1235
+ version. They are equivalent to bottom and top respectively,
1236
+ and it is an error to pass both *ymin* and *bottom* or
1237
+ *ymax* and *top*.
1238
+
1239
+ Returns
1240
+ -------
1241
+ ylimits : tuple
1242
+ Returns the new y-axis limits as (*bottom*, *top*).
1243
+
1244
+ Notes
1245
+ -----
1246
+ The *bottom* value must be less than the *top* value, or a
1247
+ ValueError is raised.
1248
+ """
1249
+
1250
+ if ymin is not None :
1251
+ if bottom is not None :
1252
+ raise ValueError ('Cannot supply both positional "bottom" '
1253
+ 'argument and kwarg "ymin"' )
1254
+ else :
1255
+ bottom = ymin
1256
+ if ymax is not None :
1257
+ if top is not None :
1258
+ raise ValueError ('Cannot supply both positional "top" '
1259
+ 'argument and kwarg "ymax"' )
1260
+ else :
1261
+ top = ymax
1262
+ if top is None and len (bottom ) == 2 :
1263
+ top = bottom [1 ]
1264
+ bottom = bottom [0 ]
1265
+
1266
+ return super ().set_ylim (bottom = bottom , top = top , emit = emit , auto = auto )
1191
1267
1192
1268
def get_rlabel_position (self ):
1193
1269
"""
0 commit comments