Skip to content

Commit c1fc073

Browse files
committed
polar: Update Axes patch as part of transform update
Instead of generating a throwaway `Wedge` class to calculate the bounding 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 2c1ec43 commit c1fc073

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
@@ -717,6 +717,8 @@ class _WedgeBbox(mtransforms.Bbox):
717717
"""
718718
Transform (theta, r) wedge Bbox into Axes bounding box.
719719
720+
Additionally, this class will update the Axes patch, if set by `_set_wedge`.
721+
720722
Parameters
721723
----------
722724
center : (float, float)
@@ -731,6 +733,7 @@ def __init__(self, center, viewLim, originLim, **kwargs):
731733
self._center = center
732734
self._viewLim = viewLim
733735
self._originLim = originLim
736+
self._wedge = None
734737
self.set_children(viewLim, originLim)
735738

736739
__str__ = mtransforms._make_str_method("_center", "_viewLim", "_originLim")
@@ -753,10 +756,22 @@ def get_points(self):
753756
width = min(points[1, 1] - points[0, 1], 0.5)
754757

755758
# Generate bounding box for wedge.
756-
wedge = mpatches.Wedge(self._center, points[1, 1],
757-
points[0, 0], points[1, 0],
758-
width=width)
759-
self.update_from_path(wedge.get_path())
759+
if self._wedge is None:
760+
# A PolarAxes subclass may not generate a Wedge as Axes patch and call
761+
# _WedgeBbox._set_wedge, so use a temporary instance to calculate the
762+
# bounds instead.
763+
wedge = mpatches.Wedge(self._center, points[1, 1],
764+
points[0, 0], points[1, 0],
765+
width=width)
766+
else:
767+
# Update the owning Axes' patch.
768+
wedge = self._wedge
769+
wedge.set_center(self._center)
770+
wedge.set_theta1(points[0, 0])
771+
wedge.set_theta2(points[1, 0])
772+
wedge.set_radius(points[1, 1])
773+
wedge.set_width(width)
774+
self.update_from_path(wedge.get_path(), ignore=True)
760775

761776
# Ensure equal aspect ratio.
762777
w, h = self._points[1] - self._points[0]
@@ -768,6 +783,11 @@ def get_points(self):
768783

769784
return self._points
770785

786+
def _set_wedge(self, wedge):
787+
"""Set the wedge patch to update when the transform changes."""
788+
_api.check_isinstance(mpatches.Wedge, wedge=wedge)
789+
self._wedge = wedge
790+
771791

772792
class PolarAxes(Axes):
773793
"""
@@ -958,31 +978,15 @@ def get_yaxis_text2_transform(self, pad):
958978

959979
def draw(self, renderer):
960980
self._unstale_viewLim()
961-
thetamin, thetamax = np.rad2deg(self._realViewLim.intervalx)
962-
if thetamin > thetamax:
963-
thetamin, thetamax = thetamax, thetamin
964-
rmin, rmax = ((self._realViewLim.intervaly - self.get_rorigin()) *
965-
self.get_rsign())
981+
self.axesLim.get_points() # Unstale bbox and Axes patch.
966982
if isinstance(self.patch, mpatches.Wedge):
967983
# Backwards-compatibility: Any subclassed Axes might override the
968984
# patch to not be the Wedge that PolarAxes uses.
969-
center = self.transWedge.transform((0.5, 0.5))
970-
self.patch.set_center(center)
971-
self.patch.set_theta1(thetamin)
972-
self.patch.set_theta2(thetamax)
973-
974-
edge, _ = self.transWedge.transform((1, 0))
975-
radius = edge - center[0]
976-
width = min(radius * (rmax - rmin) / rmax, radius)
977-
self.patch.set_radius(radius)
978-
self.patch.set_width(width)
979-
980-
inner_width = radius - width
981985
inner = self.spines.get('inner', None)
982986
if inner:
983-
inner.set_visible(inner_width != 0.0)
987+
inner.set_visible(self.patch.r != self.patch.width)
984988

985-
visible = not _is_full_circle_deg(thetamin, thetamax)
989+
visible = not _is_full_circle_rad(*self._realViewLim.intervalx)
986990
# For backwards compatibility, any subclassed Axes might override the
987991
# spines to not include start/end that PolarAxes uses.
988992
start = self.spines.get('start', None)
@@ -1002,8 +1006,20 @@ def draw(self, renderer):
10021006

10031007
super().draw(renderer)
10041008

1009+
def _wedge_get_patch_transform(self):
1010+
# See _gen_axes_patch for the use of this function. It's not a lambda or nested
1011+
# function to not break pickling.
1012+
return self.transWedge
1013+
10051014
def _gen_axes_patch(self):
1006-
return mpatches.Wedge((0.5, 0.5), 0.5, 0.0, 360.0)
1015+
wedge = mpatches.Wedge((0.5, 0.5), 0.5, 0.0, 360.0)
1016+
self.axesLim._set_wedge(wedge)
1017+
# The caller of this function will set the wedge's transform directly to
1018+
# `self.transAxes`, but `self.axesLim` will update to a pre-`self.transWedge`
1019+
# coordinate space, so override the patch transform (which is otherwise always
1020+
# an identity transform) to get the wedge in the right coordinate space.
1021+
wedge.get_patch_transform = self._wedge_get_patch_transform
1022+
return wedge
10071023

10081024
def _gen_axes_spines(self):
10091025
spines = {

0 commit comments

Comments
 (0)