From fc0ee8f41b3f83402af7811fca9e5cae522802cd Mon Sep 17 00:00:00 2001 From: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> Date: Mon, 30 Jun 2025 10:39:29 +0200 Subject: [PATCH] Backport PR #30223: Polar log scale: fix inner patch boundary and spine location --- lib/matplotlib/projections/polar.py | 8 +++++++- lib/matplotlib/spines.py | 8 +++++++- lib/matplotlib/tests/test_polar.py | 20 ++++++++++++++++++++ lib/matplotlib/tests/test_spines.py | 12 ++++++++++++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/projections/polar.py b/lib/matplotlib/projections/polar.py index 7fe6045039b1..2630a7dac3aa 100644 --- a/lib/matplotlib/projections/polar.py +++ b/lib/matplotlib/projections/polar.py @@ -857,6 +857,10 @@ def _init_axis(self): self.xaxis = ThetaAxis(self, clear=False) self.yaxis = RadialAxis(self, clear=False) self.spines['polar'].register_axis(self.yaxis) + inner_spine = self.spines.get('inner', None) + if inner_spine is not None: + # Subclasses may not have inner spine. + inner_spine.register_axis(self.yaxis) def _set_lim_and_transforms(self): # A view limit where the minimum radius can be locked if the user @@ -1002,7 +1006,9 @@ def draw(self, renderer): thetamin, thetamax = np.rad2deg(self._realViewLim.intervalx) if thetamin > thetamax: thetamin, thetamax = thetamax, thetamin - rmin, rmax = ((self._realViewLim.intervaly - self.get_rorigin()) * + rscale_tr = self.yaxis.get_transform() + rmin, rmax = ((rscale_tr.transform(self._realViewLim.intervaly) - + rscale_tr.transform(self.get_rorigin())) * self.get_rsign()) if isinstance(self.patch, mpatches.Wedge): # Backwards-compatibility: Any subclassed Axes might override the diff --git a/lib/matplotlib/spines.py b/lib/matplotlib/spines.py index 7e77a393f2a2..9732a2f3347a 100644 --- a/lib/matplotlib/spines.py +++ b/lib/matplotlib/spines.py @@ -265,11 +265,17 @@ def _adjust_location(self): self._path = mpath.Path.arc(np.rad2deg(low), np.rad2deg(high)) if self.spine_type == 'bottom': - rmin, rmax = self.axes.viewLim.intervaly + if self.axis is None: + tr = mtransforms.IdentityTransform() + else: + tr = self.axis.get_transform() + rmin, rmax = tr.transform(self.axes.viewLim.intervaly) try: rorigin = self.axes.get_rorigin() except AttributeError: rorigin = rmin + else: + rorigin = tr.transform(rorigin) scaled_diameter = (rmin - rorigin) / (rmax - rorigin) self._height = scaled_diameter self._width = scaled_diameter diff --git a/lib/matplotlib/tests/test_polar.py b/lib/matplotlib/tests/test_polar.py index 87c8efe3045e..844ab8cf3a06 100644 --- a/lib/matplotlib/tests/test_polar.py +++ b/lib/matplotlib/tests/test_polar.py @@ -482,6 +482,26 @@ def test_polar_log(): ax.plot(np.linspace(0, 2 * np.pi, n), np.logspace(0, 2, n)) +@check_figures_equal() +def test_polar_log_rorigin(fig_ref, fig_test): + # Test that equivalent linear and log radial settings give the same axes patch + # and spines. + ax_ref = fig_ref.add_subplot(projection='polar', facecolor='red') + ax_ref.set_rlim(0, 2) + ax_ref.set_rorigin(-3) + ax_ref.set_rticks(np.linspace(0, 2, 5)) + + ax_test = fig_test.add_subplot(projection='polar', facecolor='red') + ax_test.set_rscale('log') + ax_test.set_rlim(1, 100) + ax_test.set_rorigin(10**-3) + ax_test.set_rticks(np.logspace(0, 2, 5)) + + for ax in ax_ref, ax_test: + # Radial tick labels should be the only difference, so turn them off. + ax.tick_params(labelleft=False) + + def test_polar_neg_theta_lims(): fig = plt.figure() ax = fig.add_subplot(projection='polar') diff --git a/lib/matplotlib/tests/test_spines.py b/lib/matplotlib/tests/test_spines.py index 29b4ecf6f330..99b8461ad851 100644 --- a/lib/matplotlib/tests/test_spines.py +++ b/lib/matplotlib/tests/test_spines.py @@ -154,3 +154,15 @@ def test_spines_black_axes(): ax.set_xticks([]) ax.set_yticks([]) ax.set_facecolor((0, 0, 0)) + + +def test_arc_spine_inner_no_axis(): + # Backcompat: smoke test that inner arc spine does not need a registered + # axis in order to be drawn + fig = plt.figure() + ax = fig.add_subplot(projection="polar") + inner_spine = ax.spines["inner"] + inner_spine.register_axis(None) + assert ax.spines["inner"].axis is None + + fig.draw_without_rendering() pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy