8000 Handle CLOSEPOLY's in Path.interpolated · matplotlib/matplotlib@4c43570 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4c43570

Browse files
committed
Handle CLOSEPOLY's in Path.interpolated
1 parent a53d4f1 commit 4c43570

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

lib/matplotlib/path.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ def interpolated(self, steps):
669669
"""
670670
Return a new path with each segment divided into *steps* parts.
671671
672-
Codes other than `LINETO` and `MOVETO` are not handled correctly.
672+
Codes other than `LINETO`, `MOVETO`, and `CLOSEPOLY` are not handled correctly.
673673
674674
Parameters
675675
----------
@@ -688,7 +688,14 @@ def interpolated(self, steps):
688688
return self.make_compound_path(
689689
*(p.interpolated(steps) for p in self._iter_connected_components()))
690690

691-
vertices = simple_linear_interpolation(self.vertices, steps)
691+
if self.codes is not None and self.CLOSEPOLY in self.codes and not np.all(
692+
self.vertices[self.codes == self.CLOSEPOLY] == self.vertices[0]):
693+
vertices = self.vertices.copy()
694+
vertices[self.codes == self.CLOSEPOLY] = vertices[0]
695+
else:
696+
vertices = self.vertices
697+
698+
vertices = simple_linear_interpolation(vertices, steps)
692699
codes = self.codes
693700
if codes is not None:
694701
new_codes = np.full((len(codes) - 1) * steps + 1, Path.LINETO,

lib/matplotlib/tests/test_path.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,3 +559,61 @@ def test_interpolated_moveto():
559559
# Result should have two subpaths with six LINETOs each
560560
expected_subpath_codes = [Path.MOVETO] + [Path.LINETO] * 6
561561
np.testing.assert_array_equal(result.codes, expected_subpath_codes * 2)
562+
563+
564+
def test_interpolated_closepoly():
565+
codes = [Path.MOVETO] + [Path.LINETO]*2 + [Path.CLOSEPOLY]
566+
vertices = [(4, 3), (5, 4), (5, 3), (0, 0)]
567+
568+
path = Path(vertices, codes)
569+
result = path.interpolated(2)
570+
571+
expected_vertices = np.array([[4, 3],
572+
[4.5, 3.5],
573+
[5, 4],
574+
[5, 3.5],
575+
[5, 3],
576+
[4.5, 3],
577+
[4, 3]])
578+
expected_codes = [Path.MOVETO] + [Path.LINETO]*5 + [Path.CLOSEPOLY]
579+
580+
np.testing.assert_allclose(result.vertices, expected_vertices)
581+
np.testing.assert_array_equal(result.codes, expected_codes)
582+
583+
# Usually closepoly is the last vertex but does not have to be.
584+
codes += [Path.LINETO]
585+
vertices += [(2, 1)]
586+
587+
path = Path(vertices, codes)
588+
result = path.interpolated(2)
589+
590+
extra_expected_vertices = np.array([[3, 2],
591+
[2, 1]])
592+
expected_vertices = np.concatenate([expected_vertices, extra_expected_vertices])
593+
594+
expected_codes += [Path.LINETO] * 2
595+
596+
np.testing.assert_allclose(result.vertices, expected_vertices)
597+
np.testing.assert_array_equal(result.codes, expected_codes)
598+
599+
600+
def test_interpolated_moveto_closepoly():
601+
# Initial path has two closed subpaths
602+
codes = ([Path.MOVETO] + [Path.LINETO]*2 + [Path.CLOSEPOLY]) * 2
603+
vertices = [(4, 3), (5, 4), (5, 3), (0, 0), (8, 6), (10, 8), (10, 6), (0, 0)]
604+
605+
path = Path(vertices, codes)
606+
result = path.interpolated(2)
607+
608+
expected_vertices1 = np.array([[4, 3],
609+
[4.5, 3.5],
610+
[5, 4],
611+
[5, 3.5],
612+
[5, 3],
613+
[4.5, 3],
614+
[4, 3]])
615+
expected_vertices = np.concatenate([expected_vertices1, expected_vertices1 * 2])
616+
expected_codes = ([Path.MOVETO] + [Path.LINETO]*5 + [Path.CLOSEPOLY]) * 2
617+
618+
np.testing.assert_allclose(result.vertices, expected_vertices)
619+
np.testing.assert_array_equal(result.codes, expected_codes)

0 commit comments

Comments
 (0)
0