From eb4b15b47a4d019f0e9edb2fb0587aebc2dbd8e8 Mon Sep 17 00:00:00 2001 From: Bruno Beltran Date: Wed, 18 Mar 2020 12:00:54 -0700 Subject: [PATCH 1/2] fix bug where make_compound_path kept all STOPs --- lib/matplotlib/path.py | 11 +++++++++++ lib/matplotlib/tests/test_path.py | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/lib/matplotlib/path.py b/lib/matplotlib/path.py index 93165dc684dc..f56746b88dea 100644 --- a/lib/matplotlib/path.py +++ b/lib/matplotlib/path.py @@ -330,6 +330,7 @@ def make_compound_path(cls, *args): if not args: return Path(np.empty([0, 2], dtype=np.float32)) + # concatenate paths vertices = np.concatenate([x.vertices for x in args]) codes = np.empty(len(vertices), dtype=cls.code_type) i = 0 @@ -341,6 +342,16 @@ def make_compound_path(cls, *args): codes[i:i + len(path.codes)] = path.codes i += len(path.vertices) + # remove internal STOP's, replace kinal stop if present + last_vert = None + if codes.size > 0 and codes[-1] == cls.STOP: + last_vert = vertices[-1] + vertices = vertices[codes != cls.STOP, :] + codes = codes[codes != cls.STOP] + if last_vert is not None: + vertices = np.append(vertices, [last_vert], axis=0) + codes = np.append(codes, cls.STOP) + return cls(vertices, codes) def __repr__(self): diff --git a/lib/matplotlib/tests/test_path.py b/lib/matplotlib/tests/test_path.py index 4435b2337bef..8a90ca6f2379 100644 --- a/lib/matplotlib/tests/test_path.py +++ b/lib/matplotlib/tests/test_path.py @@ -147,6 +147,13 @@ def test_make_compound_path_empty(): assert r.vertices.shape == (0, 2) +def test_make_compound_path_stops(): + zero = [0, 0] + paths = 3*[Path([zero, zero], [Path.MOVETO, Path.STOP])] + compound_path = Path.make_compound_path(*paths) + assert np.sum(compound_path.codes == Path.STOP) == 1 + + @image_comparison(['xkcd.png'], remove_text=True) def test_xkcd(): np.random.seed(0) From 95b33b1c442f425eeb2a7b111a76bef1541e554a Mon Sep 17 00:00:00 2001 From: Bruno Beltran Date: Wed, 18 Mar 2020 14:51:11 -0700 Subject: [PATCH 2/2] do not retain any STOPs in make_compound_path --- lib/matplotlib/path.py | 21 ++++++++------------- lib/matplotlib/tests/test_path.py | 4 +++- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/lib/matplotlib/path.py b/lib/matplotlib/path.py index f56746b88dea..7db416408e11 100644 --- a/lib/matplotlib/path.py +++ b/lib/matplotlib/path.py @@ -325,12 +325,13 @@ def make_compound_path_from_polys(cls, XY): @classmethod def make_compound_path(cls, *args): - """Make a compound path from a list of Path objects.""" + """ + Make a compound path from a list of Path objects. Blindly removes all + Path.STOP control points. + """ # Handle an empty list in args (i.e. no args). if not args: return Path(np.empty([0, 2], dtype=np.float32)) - - # concatenate paths vertices = np.concatenate([x.vertices for x in args]) codes = np.empty(len(vertices), dtype=cls.code_type) i = 0 @@ -341,16 +342,10 @@ def make_compound_path(cls, *args): else: codes[i:i + len(path.codes)] = path.codes i += len(path.vertices) - - # remove internal STOP's, replace kinal stop if present - last_vert = None - if codes.size > 0 and codes[-1] == cls.STOP: - last_vert = vertices[-1] - vertices = vertices[codes != cls.STOP, :] - codes = codes[codes != cls.STOP] - if last_vert is not None: - vertices = np.append(vertices, [last_vert], axis=0) - codes = np.append(codes, cls.STOP) + # remove STOP's, since internal STOPs are a bug + not_stop_mask = codes != cls.STOP + vertices = vertices[not_stop_mask, :] + codes = codes[not_stop_mask] return cls(vertices, codes) diff --git a/lib/matplotlib/tests/test_path.py b/lib/matplotlib/tests/test_path.py index 8a90ca6f2379..b61a92654dc3 100644 --- a/lib/matplotlib/tests/test_path.py +++ b/lib/matplotlib/tests/test_path.py @@ -151,7 +151,9 @@ def test_make_compound_path_stops(): zero = [0, 0] paths = 3*[Path([zero, zero], [Path.MOVETO, Path.STOP])] compound_path = Path.make_compound_path(*paths) - assert np.sum(compound_path.codes == Path.STOP) == 1 + # the choice to not preserve the terminal STOP is arbitrary, but + # documented, so we test that it is in fact respected here + assert np.sum(compound_path.codes == Path.STOP) == 0 @image_comparison(['xkcd.png'], remove_text=True)