Skip to content

Commit 5c6d199

Browse files
committed
FIX: Ensure Locators on RadialAxis are always correctly wrapped
All the wrapping logic is now contained in RadialAxis Closes matplotlib#30164 and rearchitects matplotlib#29798.
1 parent f6b77d2 commit 5c6d199

File tree

2 files changed

+52
-17
lines changed

2 files changed

+52
-17
lines changed

lib/matplotlib/projections/polar.py

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -680,19 +680,20 @@ def __init__(self, *args, **kwargs):
680680
self.sticky_edges.y.append(0)
681681

682682
def _wrap_locator_formatter(self):
683-
self.set_major_locator(RadialLocator(self.get_major_locator(),
684-
self.axes))
685-
self.isDefault_majloc = True
683+
if not isinstance(self.get_major_locator(), RadialLocator):
684+
is_default = self.isDefault_majloc
685+
super().set_major_locator(
686+
RadialLocator(self.get_major_locator(), self.axes))
687+
self.isDefault_majloc = is_default
688+
689+
def set_major_locator(self, locator):
690+
super().set_major_locator(locator)
691+
self._wrap_locator_formatter()
686692

687693
def clear(self):
688694
# docstring inherited
689695
super().clear()
690696
self.set_ticks_position('none')
691-
self._wrap_locator_formatter()
692-
693-
def _set_scale(self, value, **kwargs):
694-
super()._set_scale(value, **kwargs)
695-
self._wrap_locator_formatter()
696697

697698

698699
def _is_full_circle_deg(thetamin, thetamax):
@@ -1242,19 +1243,11 @@ def set_rlabel_position(self, value):
12421243
"""
12431244
self._r_label_position.clear().translate(np.deg2rad(value), 0.0)
12441245

1245-
def set_yscale(self, *args, **kwargs):
1246-
super().set_yscale(*args, **kwargs)
1247-
self.yaxis.set_major_locator(
1248-
self.RadialLocator(self.yaxis.get_major_locator(), self))
1249-
12501246
def set_rscale(self, *args, **kwargs):
12511247
return Axes.set_yscale(self, *args, **kwargs)
12521248

12531249
def set_rticks(self, *args, **kwargs):
1254-
result = Axes.set_yticks(self, *args, **kwargs)
1255-
self.yaxis.set_major_locator(
1256-
self.RadialLocator(self.yaxis.get_major_locator(), self))
1257-
return result
1250+
return Axes.set_yticks(self, *args, **kwargs)
12581251

12591252
def set_thetagrids(self, angles, labels=None, fmt=None, **kwargs):
12601253
"""

lib/matplotlib/tests/test_polar.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
import pytest
44

55
import matplotlib as mpl
6+
from matplotlib.projections.polar import RadialLocator
67
from matplotlib import pyplot as plt
78
from matplotlib.testing.decorators import image_comparison, check_figures_equal
9+
import matplotlib.ticker as mticker
810

911

1012
@image_comparison(['polar_axes.png'], style='default', tol=0.012)
@@ -526,3 +528,43 @@ def test_radial_limits_behavior():
526528
# negative data also autoscales to negative limits
527529
ax.plot([1, 2], [-1, -2])
528530
assert ax.get_ylim() == (-2, 2)
531+
532+
533+
def test_radial_locator_wrapping():
534+
# Check that the locator is always wrapped inside a RadialLocator
535+
# and that RaidialAxis.isDefault_majloc is set correctly.
536+
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
537+
assert ax.yaxis.isDefault_majloc
538+
assert isinstance(ax.yaxis.get_major_locator(), RadialLocator)
539+
540+
# set an explicit locator
541+
locator = mticker.MaxNLocator(3)
542+
ax.yaxis.set_major_locator(locator)
543+
assert not ax.yaxis.isDefault_majloc
544+
assert isinstance(ax.yaxis.get_major_locator(), RadialLocator)
545+
assert ax.yaxis.get_major_locator().base is locator
546+
547+
ax.clear() # reset to the default locator
548+
assert ax.yaxis.isDefault_majloc
549+
assert isinstance(ax.yaxis.get_major_locator(), RadialLocator)
550+
551+
ax.set_rticks([0, 1, 2, 3]) # implicitly sets a FixedLocator
552+
assert not ax.yaxis.isDefault_majloc # because of the fixed ticks
553+
assert isinstance(ax.yaxis.get_major_locator(), RadialLocator)
554+
assert isinstance(ax.yaxis.get_major_locator().base, mticker.FixedLocator)
555+
556+
ax.clear()
557+
558+
ax.set_rgrids([0, 1, 2, 3]) # implicitly sets a FixedLocator
559+
assert not ax.yaxis.isDefault_majloc # because of the fixed ticks
560+
assert isinstance(ax.yaxis.get_major_locator(), RadialLocator)
561+
assert isinstance(ax.yaxis.get_major_locator().base, mticker.FixedLocator)
562+
563+
ax.clear()
564+
565+
ax.set_yscale("log") # implicitly sets a LogLocator
566+
# Note that the LogLocator is still considered the default locator
567+
# for the log scale
568+
assert ax.yaxis.isDefault_majloc
569+
assert isinstance(ax.yaxis.get_major_locator(), RadialLocator)
570+
assert isinstance(ax.yaxis.get_major_locator().base, mticker.LogLocator)

0 commit comments

Comments
 (0)