Skip to content

Commit 4331c53

Browse files
authored
Merge pull request matplotlib#14852 from anntzer/polarinterp
ENH: Use Path.arc() to interpolate polar arcs.
2 parents a27b73c + 73a763a commit 4331c53

29 files changed

+2541
-7335
lines changed

lib/matplotlib/projections/polar.py

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import matplotlib.axis as maxis
99
import matplotlib.markers as mmarkers
1010
import matplotlib.patches as mpatches
11-
import matplotlib.path as mpath
11+
from matplotlib.path import Path
1212
import matplotlib.ticker as mticker
1313
import matplotlib.transforms as mtransforms
1414
import matplotlib.spines as mspines
@@ -50,11 +50,57 @@ def transform_non_affine(self, tr):
5050

5151
def transform_path_non_affine(self, path):
5252
# docstring inherited
53-
vertices = path.vertices
54-
if len(vertices) == 2 and vertices[0, 0] == vertices[1, 0]:
55-
return mpath.Path(self.transform(vertices), path.codes)
56-
ipath = path.interpolated(path._interpolation_steps)
57-
return mpath.Path(self.transform(ipath.vertices), ipath.codes)
53+
if not len(path) or path._interpolation_steps == 1:
54+
return Path(self.transform_non_affine(path.vertices), path.codes)
55+
xys = []
56+
codes = []
57+
last_t = last_r = None
58+
for trs, c in path.iter_segments():
59+
trs = trs.reshape((-1, 2))
60+
if c == Path.LINETO:
61+
(t, r), = trs
62+
if t == last_t: # Same angle: draw a straight line.
63+
xys.extend(self.transform_non_affine(trs))
64+
codes.append(Path.LINETO)
65+
elif r == last_r: # Same radius: draw an arc.
66+
# The following is complicated by Path.arc() being
67+
# "helpful" and unwrapping the angles, but we don't want
68+
# that behavior here.
69+
last_td, td = np.rad2deg([last_t, t])
70+
if self._use_rmin and self._axis is not None:
71+
r = ((r - self._axis.get_rorigin())
72+
* self._axis.get_rsign())
73+
if last_td <= td:
74+
while td - last_td > 360:
75+
arc = Path.arc(last_td, last_td + 360)
76+
xys.extend(arc.vertices[1:] * r)
77+
codes.extend(arc.codes[1:])
78+
last_td += 360
79+
arc = Path.arc(last_td, td)
80+
xys.extend(arc.vertices[1:] * r)
81+
codes.extend(arc.codes[1:])
82+
else:
83+
# The reverse version also relies on the fact that all
84+
# codes but the first one are the same.
85+
while last_td - td > 360:
86+
arc = Path.arc(last_td - 360, last_td)
87+
xys.extend(arc.vertices[::-1][1:] * r)
88+
codes.extend(arc.codes[1:])
89+
last_td -= 360
90+
arc = Path.arc(td, last_td)
91+
xys.extend(arc.vertices[::-1][1:] * r)
92+
codes.extend(arc.codes[1:])
93+
else: # Interpolate.
94+
trs = cbook.simple_linear_interpolation(
95+
np.row_stack([(last_t, last_r), trs]),
96+
path._interpolation_steps)[1:]
97+
xys.extend(self.transform_non_affine(trs))
98+
codes.extend([Path.LINETO] * len(trs))
99+
else: # Not a straight line.
100+
xys.extend(self.transform_non_affine(trs))
101+
codes.extend([c] * len(trs))
102+
last_t, last_r = trs[-1]
103+
return Path(xys, codes)
58104

59105
def inverted(self):
60106
# docstring inherited
Binary file not shown.
Loading

lib/matplotlib/tests/baseline_images/test_axes/markevery_polar.svg

Lines changed: 704 additions & 1199 deletions
Loading
Loading
Binary file not shown.
Loading

0 commit comments

Comments
 (0)