Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5ff6a93

Browse filesBrowse files
authored
Merge pull request #29919 from rcomer/geo-contour
2 parents 126515a + f24001a commit 5ff6a93
Copy full SHA for 5ff6a93

File tree

Expand file treeCollapse file tree

2 files changed

+106
-4
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+106
-4
lines changed

‎lib/matplotlib/path.py

Copy file name to clipboardExpand all lines: lib/matplotlib/path.py
+25-4Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -667,14 +667,35 @@ def intersects_bbox(self, bbox, filled=True):
667667

668668
def interpolated(self, steps):
669669
"""
670-
Return a new path resampled to length N x *steps*.
670+
Return a new path with each segment divided into *steps* parts.
671671
672-
Codes other than `LINETO` are not handled correctly.
672+
Codes other than `LINETO`, `MOVETO`, and `CLOSEPOLY` are not handled correctly.
673+
674+
Parameters
675+
----------
676+
steps : int
677+
The number of segments in the new path for each in the original.
678+
679+
Returns
680+
-------
681+
Path
682+
The interpolated path.
673683
"""
674-
if steps == 1:
684+
if steps == 1 or len(self) == 0:
675685
return self
676686

677-
vertices = simple_linear_interpolation(self.vertices, steps)
687+
if self.codes is not None and self.MOVETO in self.codes[1:]:
688+
return self.make_compound_path(
689+
*(p.interpolated(steps) for p in self._iter_connected_components()))
690+
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)
678699
codes = self.codes
679700
if codes is not None:
680701
new_codes = np.full((len(codes) - 1) * steps + 1, Path.LINETO,

‎lib/matplotlib/tests/test_path.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_path.py
+81Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,3 +541,84 @@ def test_cleanup_closepoly():
541541
cleaned = p.cleaned(remove_nans=True)
542542
assert len(cleaned) == 1
543543
assert cleaned.codes[0] == Path.STOP
544+
545+
546+
def test_interpolated_moveto():
547+
# Initial path has two subpaths with two LINETOs each
548+
vertices = np.array([[0, 0],
549+
[0, 1],
550+
[1, 2],
551+
[4, 4],
552+
[4, 5],
553+
[5, 5]])
554+
codes = [Path.MOVETO, Path.LINETO, Path.LINETO] * 2
555+
556+
path = Path(vertices, codes)
557+
result = path.interpolated(3)
558+
559+
# Result should have two subpaths with six LINETOs each
560+
expected_subpath_codes = [Path.MOVETO] + [Path.LINETO] * 6
561+
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)
620+
621+
622+
def test_interpolated_empty_path():
623+
path = Path(np.zeros((0, 2)))
624+
assert path.interpolated(42) is path

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.