Skip to content

Commit 4f3daae

Browse files
committed
polar: Update Axes patch as part of transform update
Instead of generating a throwaway `Wedge` class to calculate the boundaing box for sizing, re-use the one that is the `Axes` patch (unless it was never set). This also removes the redundant re-calculation to resize the `Axes` patch during draw. This does in turn require tweaking the transform, as the calculation uses a slightly different domain, but it should be more robust to changes in the bbox calculation.
1 parent 51e7230 commit 4f3daae

File tree

1 file changed

+40
-24
lines changed

1 file changed

+40
-24
lines changed

lib/matplotlib/projections/polar.py

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,8 @@ class _WedgeBbox(mtransforms.Bbox):
757757
"""
758758
Transform (theta, r) wedge Bbox into Axes bounding box.
759759
760+
Additionally, this class will update the Axes patch, if set by `_set_wedge`.
761+
760762
Parameters
761763
----------
762764
center : (float, float)
@@ -771,6 +773,7 @@ def __init__(self, center, viewLim, originLim, **kwargs):
771773
self._center = center
772774
self._viewLim = viewLim
773775
self._originLim = originLim
776+
self._wedge = None
774777
self.set_children(viewLim, originLim)
775778

776779
__str__ = mtransforms._make_str_method("_center", "_viewLim", "_originLim")
@@ -793,10 +796,22 @@ def get_points(self):
793796
width = min(points[1, 1] - points[0, 1], 0.5)
794797

795798
# Generate bounding box for wedge.
796-
wedge = mpatches.Wedge(self._center, points[1, 1],
797-
points[0, 0], points[1, 0],
798-
width=width)
799-
self.update_from_path(wedge.get_path())
799+
if self._wedge is None:
800+
# A PolarAxes subclass may not generate a Wedge as Axes patch and call
801+
# _WedgeBbox._set_wedge, so use a temporary instance to calculate the
802+
# bounds instead.
803+
wedge = mpatches.Wedge(self._center, points[1, 1],
804+
points[0, 0], points[1, 0],
805+
width=width)
806+
else:
807+
# Update the owning Axes' patch.
808+
wedge = self._wedge
809+
wedge.set_center(self._center)
810+
wedge.set_theta1(points[0, 0])
811+
wedge.set_theta2(points[1, 0])
812+
wedge.set_radius(points[1, 1])
813+
wedge.set_width(width)
814+
self.update_from_path(wedge.get_path(), ignore=True)
800815

801816
# Ensure equal aspect ratio.
802817
w, h = self._points[1] - self._points[0]
@@ -808,6 +823,11 @@ def get_points(self):
808823

809824
return self._points
810825

826+
def _set_wedge(self, wedge):
827+
"""Set the wedge patch to update when the transform changes."""
828+
_api.check_isinstance(mpatches.Wedge, wedge=wedge)
829+
self._wedge = wedge
830+
811831

812832
class PolarAxes(Axes):
813833
"""
@@ -999,31 +1019,15 @@ def get_yaxis_text2_transform(self, pad):
9991019

10001020
def draw(self, renderer):
10011021
self._unstale_viewLim()
1002-
thetamin, thetamax = np.rad2deg(self._realViewLim.intervalx)
1003-
if thetamin > thetamax:
1004-
thetamin, thetamax = thetamax, thetamin
1005-
rmin, rmax = ((self._realViewLim.intervaly - self.get_rorigin()) *
1006-
self.get_rsign())
1022+
self.axesLim.get_points() # Unstale bbox and Axes patch.
10071023
if isinstance(self.patch, mpatches.Wedge):
10081024
# Backwards-compatibility: Any subclassed Axes might override the
10091025
# patch to not be the Wedge that PolarAxes uses.
1010-
center = self.transWedge.transform((0.5, 0.5))
1011-
self.patch.set_center(center)
1012-
self.patch.set_theta1(thetamin)
1013-
self.patch.set_theta2(thetamax)
1014-
1015-
edge, _ = self.transWedge.transform((1, 0))
1016-
radius = edge - center[0]
1017-
width = min(radius * (rmax - rmin) / rmax, radius)
1018-
self.patch.set_radius(radius)
1019-
self.patch.set_width(width)
1020-
1021-
inner_width = radius - width
10221026
inner = self.spines.get('inner', None)
10231027
if inner:
1024-
inner.set_visible(inner_width != 0.0)
1028+
inner.set_visible(self.patch.r != self.patch.width)
10251029

1026-
visible = not _is_full_circle_deg(thetamin, thetamax)
1030+
visible = not _is_full_circle_rad(*self._realViewLim.intervalx)
10271031
# For backwards compatibility, any subclassed Axes might override the
10281032
# spines to not include start/end that PolarAxes uses.
10291033
start = self.spines.get('start', None)
@@ -1043,8 +1047,20 @@ def draw(self, renderer):
10431047

10441048
super().draw(renderer)
10451049

1050+
def _wedge_get_patch_transform(self):
1051+
# See _gen_axes_patch for the use of this function. It's not a lambda or nested
1052+
# function to not break pickling.
1053+
return self.transWedge
1054+
10461055
def _gen_axes_patch(self):
1047-
return mpatches.Wedge((0.5, 0.5), 0.5, 0.0, 360.0)
1056+
wedge = mpatches.Wedge((0.5, 0.5), 0.5, 0.0, 360.0)
1057+
self.axesLim._set_wedge(wedge)
1058+
# The caller of this function will set the wedge's transform directly to
1059+
# `self.transAxes`, but `self.axesLim` will update to a pre-`self.transWedge`
1060+
# coordinate space, so override the patch transform (which is otherwise always
1061+
# an identity transform) to get the wedge in the right coordinate space.
1062+
wedge.get_patch_transform = self._wedge_get_patch_transform
1063+
return wedge
10481064

10491065
def _gen_axes_spines(self):
10501066
spines = {

0 commit comments

Comments
 (0)