1616
1717
1818class PolarTransform (mtransforms .Transform ):
19- """
19+ r """
2020 The base polar transform.
2121
22- This transform maps polar coordinates ``(theta, r)`` into Cartesian
23- coordinates ``(x, y) = (r * cos(theta), r * sin(theta))`` (but does not
22+ This transform maps polar coordinates :math:`\theta, r` into Cartesian
23+ coordinates :math:`x, y = r \cos(\theta), r \sin(\theta)`
24+ (but does not fully transform into Axes coordinates or
2425 handle positioning in screen space).
2526
27+ This transformation is designed to be applied to data after any scaling
28+ along the radial axis (e.g. log-scaling) has been applied to the input
29+ data.
30+
2631 Path segments at a fixed radius are automatically transformed to circular
2732 arcs as long as ``path._interpolation_steps > 1``.
2833 """
2934
3035 input_dims = output_dims = 2
3136
3237 def __init__ (self , axis = None , use_rmin = True ,
33- _apply_theta_transforms = True ):
38+ _apply_theta_transforms = True , * , scale_transform = None ):
3439 """
3540 Parameters
3641 ----------
@@ -46,12 +51,18 @@ def __init__(self, axis=None, use_rmin=True,
4651 self ._axis = axis
4752 self ._use_rmin = use_rmin
4853 self ._apply_theta_transforms = _apply_theta_transforms
54+ self ._scale_transform = scale_transform
4955
5056 __str__ = mtransforms ._make_str_method (
5157 "_axis" ,
5258 use_rmin = "_use_rmin" ,
5359 _apply_theta_transforms = "_apply_theta_transforms" )
5460
61+ def _get_rorigin (self ):
62+ # Get lower r limit after being scaled by the radial scale transform
63+ return self ._scale_transform .transform (
64+ (0 , self ._axis .get_rorigin ()))[1 ]
65+
5566 def transform_non_affine (self , tr ):
5667 # docstring inherited
5768 theta , r = np .transpose (tr )
@@ -61,7 +72,7 @@ def transform_non_affine(self, tr):
6172 theta *= self ._axis .get_theta_direction ()
6273 theta += self ._axis .get_theta_offset ()
6374 if self ._use_rmin and self ._axis is not None :
64- r = (r - self ._axis . get_rorigin ()) * self ._axis .get_rsign ()
75+ r = (r - self ._get_rorigin ()) * self ._axis .get_rsign ()
6576 r = np .where (r >= 0 , r , np .nan )
6677 return np .column_stack ([r * np .cos (theta ), r * np .sin (theta )])
6778
@@ -85,7 +96,7 @@ def transform_path_non_affine(self, path):
8596 # that behavior here.
8697 last_td , td = np .rad2deg ([last_t , t ])
8798 if self ._use_rmin and self ._axis is not None :
88- r = ((r - self ._axis . get_rorigin ())
99+ r = ((r - self ._get_rorigin ())
89100 * self ._axis .get_rsign ())
90101 if last_td <= td :
91102 while td - last_td > 360 :
@@ -877,7 +888,9 @@ def _set_lim_and_transforms(self):
877888 # data. This one is aware of rmin
878889 self .transProjection = self .PolarTransform (
879890 self ,
880- _apply_theta_transforms = False )
891+ _apply_theta_transforms = False ,
892+ scale_transform = self .transScale
893+ )
881894 # Add dependency on rorigin.
882895 self .transProjection .set_children (self ._originViewLim )
883896
@@ -888,9 +901,25 @@ def _set_lim_and_transforms(self):
888901
889902 # The complete data transformation stack -- from data all the
890903 # way to display coordinates
904+ #
905+ # 1. Remove any radial axis scaling (e.g. log scaling)
906+ # 2. Shift data in the theta direction
907+ # 3. Project the data from polar to cartesian values
908+ # (with the origin in the same place)
909+ # 4. Scale and translate the cartesian values to Axes coordinates
910+ # (here the origin is moved to the lower left of the Axes)
911+ # 5. Move and scale to fill the Axes
912+ # 6. Convert from Axes coordinates to Figure coordinates
891913 self .transData = (
892- self .transScale + self .transShift + self .transProjection +
893- (self .transProjectionAffine + self .transWedge + self .transAxes ))
914+ self .transScale +
915+ self .transShift +
916+ self .transProjection +
917+ (
918+ self .transProjectionAffine +
919+ self .transWedge +
920+ self .transAxes
921+ )
922+ )
894923
895924 # This is the transform for theta-axis ticks. It is
896925 # equivalent to transData, except it always puts r == 0.0 and r == 1.0
0 commit comments