From bcca61026377ac1bede90ff8f65cf33572f811bb Mon Sep 17 00:00:00 2001 From: Scott Shambaugh Date: Wed, 1 Jan 2025 23:33:26 -0700 Subject: [PATCH 1/3] Faster Path creation --- lib/matplotlib/collections.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index 2e72926cbe5d..a4946178e5a5 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -1246,11 +1246,12 @@ def set_verts(self, verts, closed=True): verts_pad = np.concatenate((verts, verts[:, :1]), axis=1) # Creating the codes once is much faster than having Path do it # separately each time by passing closed=True. - codes = np.empty(verts_pad.shape[1], dtype=mpath.Path.code_type) - codes[:] = mpath.Path.LINETO - codes[0] = mpath.Path.MOVETO - codes[-1] = mpath.Path.CLOSEPOLY - self._paths = [mpath.Path(xy, codes) for xy in verts_pad] + example_path = mpath.Path(verts_pad[0], closed=True) + # Looking up the values once speeds up the iteration a bit + _make_path = mpath.Path._fast_from_codes_and_verts + codes = example_path.codes + self._paths = [_make_path(xy, codes, internals_from=example_path) + for xy in verts_pad] return self._paths = [] From 240c041792e938c726af22b64f01d69eeec48a4c Mon Sep 17 00:00:00 2001 From: Scott Shambaugh Date: Wed, 1 Jan 2025 21:40:14 -0700 Subject: [PATCH 2/3] 3d calculation speedups _to_unmasked_float_array updates Linting and tweaks mean zsort small perf gain linting Fix tests Linting and tweaks mean zsort small perf gain linting Fix tests Update lib/matplotlib/collections.py Co-authored-by: Oscar Gustafsson remove Path __slots__ Code review suggestions --- lib/matplotlib/cbook.py | 4 ++-- lib/matplotlib/collections.py | 13 ++++++------- lib/matplotlib/path.py | 1 - lib/matplotlib/tests/test_transforms.py | 2 +- lib/mpl_toolkits/mplot3d/art3d.py | 2 +- lib/mpl_toolkits/mplot3d/proj3d.py | 3 +-- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/lib/matplotlib/cbook.py b/lib/matplotlib/cbook.py index b18b935c8ead..9b26842a766c 100644 --- a/lib/matplotlib/cbook.py +++ b/lib/matplotlib/cbook.py @@ -1340,9 +1340,9 @@ def _to_unmasked_float_array(x): values are converted to nans. """ if hasattr(x, 'mask'): - return np.ma.asarray(x, float).filled(np.nan) + return np.ma.asanyarray(x, float).filled(np.nan) else: - return np.asarray(x, float) + return np.asanyarray(x, float) def _check_1d(x): diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index a4946178e5a5..a3f245bbc2c8 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -1242,15 +1242,14 @@ def set_verts(self, verts, closed=True): return # Fast path for arrays - if isinstance(verts, np.ndarray) and len(verts.shape) == 3: + if isinstance(verts, np.ndarray) and len(verts.shape) == 3 and verts.size: verts_pad = np.concatenate((verts, verts[:, :1]), axis=1) - # Creating the codes once is much faster than having Path do it - # separately each time by passing closed=True. - example_path = mpath.Path(verts_pad[0], closed=True) - # Looking up the values once speeds up the iteration a bit + # It's faster to create the codes and internal flags once in a + # template path and reuse them. + template_path = mpath.Path(verts_pad[0], closed=True) + codes = template_path.codes _make_path = mpath.Path._fast_from_codes_and_verts - codes = example_path.codes - self._paths = [_make_path(xy, codes, internals_from=example_path) + self._paths = [_make_path(xy, codes, internals_from=template_path) for xy in verts_pad] return diff --git a/lib/matplotlib/path.py b/lib/matplotlib/path.py index 5f5a0f3de423..4784410f0f5e 100644 --- a/lib/matplotlib/path.py +++ b/lib/matplotlib/path.py @@ -76,7 +76,6 @@ class Path: made up front in the constructor that will not change when the data changes. """ - code_type = np.uint8 # Path codes diff --git a/lib/matplotlib/tests/test_transforms.py b/lib/matplotlib/tests/test_transforms.py index 96e78b6828f8..83ea260c434e 100644 --- a/lib/matplotlib/tests/test_transforms.py +++ b/lib/matplotlib/tests/test_transforms.py @@ -988,7 +988,7 @@ def test_transformed_path(): atol=1e-15) # Changing the path does not change the result (it's cached). - path.points = [(0, 0)] * 4 + path._vertices = [(0, 0)] * 4 assert_allclose(trans_path.get_fully_transformed_path().vertices, [(0, 0), (r2, r2), (0, 2 * r2), (-r2, r2)], atol=1e-15) diff --git a/lib/mpl_toolkits/mplot3d/art3d.py b/lib/mpl_toolkits/mplot3d/art3d.py index 88c2ae625c00..26c3c5a28e20 100644 --- a/lib/mpl_toolkits/mplot3d/art3d.py +++ b/lib/mpl_toolkits/mplot3d/art3d.py @@ -1367,7 +1367,7 @@ def _zalpha(colors, zs): # Should really normalize against the viewing depth. if len(colors) == 0 or len(zs) == 0: return np.zeros((0, 4)) - norm = Normalize(min(zs), max(zs)) + norm = Normalize(np.min(zs), np.max(zs)) sats = 1 - norm(zs) * 0.7 rgba = np.broadcast_to(mcolors.to_rgba_array(colors), (len(zs), 4)) return np.column_stack([rgba[:, :3], rgba[:, 3] * sats]) diff --git a/lib/mpl_toolkits/mplot3d/proj3d.py b/lib/mpl_toolkits/mplot3d/proj3d.py index 34a03969c961..87c59ae05714 100644 --- a/lib/mpl_toolkits/mplot3d/proj3d.py +++ b/lib/mpl_toolkits/mplot3d/proj3d.py @@ -164,8 +164,7 @@ def _proj_transform_vectors(vecs, M): def _proj_transform_vec_clip(vec, M, focal_length): vecw = np.dot(M, vec.data) - w = vecw[3] - txs, tys, tzs = vecw[0] / w, vecw[1] / w, vecw[2] / w + txs, tys, tzs = vecw[0:3] / vecw[3] if np.isinf(focal_length): # don't clip orthographic projection tis = np.ones(txs.shape, dtype=bool) else: From c6b9214f0c7ec2ab495b494f5b83df133f7ec7ff Mon Sep 17 00:00:00 2001 From: Scott Shambaugh Date: Tue, 7 Jan 2025 11:57:56 -0700 Subject: [PATCH 3/3] Remove test --- lib/matplotlib/tests/test_transforms.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/matplotlib/tests/test_transforms.py b/lib/matplotlib/tests/test_transforms.py index 83ea260c434e..9981c54f9025 100644 --- a/lib/matplotlib/tests/test_transforms.py +++ b/lib/matplotlib/tests/test_transforms.py @@ -987,12 +987,6 @@ def test_transformed_path(): [(0, 0), (r2, r2), (0, 2 * r2), (-r2, r2)], atol=1e-15) - # Changing the path does not change the result (it's cached). - path._vertices = [(0, 0)] * 4 - assert_allclose(trans_path.get_fully_transformed_path().vertices, - [(0, 0), (r2, r2), (0, 2 * r2), (-r2, r2)], - atol=1e-15) - def test_transformed_patch_path(): trans = mtransforms.Affine2D() 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