From 5a9cd4e8dd292f83c50652746ba3e43185ad56df Mon Sep 17 00:00:00 2001 From: Eric Prestat Date: Sat, 22 Jul 2023 10:18:19 +0100 Subject: [PATCH 1/6] Add `widths`, `heights` and `angles` setter to `EllipseCollection` --- lib/matplotlib/collections.py | 12 +++++++++ lib/matplotlib/tests/test_collections.py | 31 ++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index cc20e5cebc1b..c3380c278e37 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -1795,6 +1795,18 @@ def _set_transforms(self): m[:2, 2:] = 0 self.set_transform(_affine(m)) + def set_widths(self, widths): + self._widths = 0.5 * np.asarray(widths).ravel() + self.stale = True + + def set_angles(self, angles): + self._angles = np.deg2rad(angles).ravel() + self.stale = True + + def set_heights(self, heights): + self._heights = 0.5 * np.asarray(heights).ravel() + self.stale = True + @artist.allow_rasterization def draw(self, renderer): self._set_transforms() diff --git a/lib/matplotlib/tests/test_collections.py b/lib/matplotlib/tests/test_collections.py index 5baaeaa5d388..19ad4081715a 100644 --- a/lib/matplotlib/tests/test_collections.py +++ b/lib/matplotlib/tests/test_collections.py @@ -408,6 +408,37 @@ def test_EllipseCollection(): ax.autoscale_view() +def test_EllipseCollection_setter(): + # Test widths, heights and angle setter + rng = np.random.default_rng(0) + + widths = (2, ) + heights = (3, ) + angles = (45, ) + offsets = rng.random((10, 2)) * 10 + + fig, ax = plt.subplots() + + ec = mcollections.EllipseCollection( + widths=widths, + heights=heights, + angles=angles, + offsets=offsets, + units='x', + offset_transform=ax.transData, + ) + + ax.add_collection(ec) + ax.set_xlim(-2, 12) + ax.set_ylim(-2, 12) + + new_widths = rng.random((10, 2)) * 2 + new_heights = rng.random((10, 2)) * 3 + new_angles = rng.random((10, 2)) * 180 + + ec.set(widths=new_widths, heights=new_heights, angles=new_angles) + + @image_comparison(['polycollection_close.png'], remove_text=True, style='mpl20') def test_polycollection_close(): from mpl_toolkits.mplot3d import Axes3D # type: ignore From 673fb6a2b9940740b014e09bd9e43a0798d417b0 Mon Sep 17 00:00:00 2001 From: Eric Prestat Date: Sat, 22 Jul 2023 10:50:58 +0100 Subject: [PATCH 2/6] Add whats_new entry --- .../add_EllipseCollection_setters.rst | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 doc/users/next_whats_new/add_EllipseCollection_setters.rst diff --git a/doc/users/next_whats_new/add_EllipseCollection_setters.rst b/doc/users/next_whats_new/add_EllipseCollection_setters.rst new file mode 100644 index 000000000000..d3f7b3d85f15 --- /dev/null +++ b/doc/users/next_whats_new/add_EllipseCollection_setters.rst @@ -0,0 +1,40 @@ +Add ``widths``, ``heights`` and ``angles`` setter to ``EllipseCollection`` +-------------------------------------------------------------------------- + +The ``widths``, ``heights`` and ``angles`` values of the `~matplotlib.collections.EllipseCollection` +can now be changed after the collection has been created. + +.. plot:: + :include-source: true + + import matplotlib.pyplot as plt + from matplotlib.collections import EllipseCollection + import numpy as np + + rng = np.random.default_rng(0) + + widths = (2, ) + heights = (3, ) + angles = (45, ) + offsets = rng.random((10, 2)) * 10 + + fig, ax = plt.subplots() + + ec = EllipseCollection( + widths=widths, + heights=heights, + angles=angles, + offsets=offsets, + units='x', + offset_transform=ax.transData, + ) + + ax.add_collection(ec) + ax.set_xlim(-2, 12) + ax.set_ylim(-2, 12) + + new_widths = rng.random((10, 2)) * 2 + new_heights = rng.random((10, 2)) * 3 + new_angles = rng.random((10, 2)) * 180 + + ec.set(widths=new_widths, heights=new_heights, angles=new_angles) From f7be1b6e717c713af227c3f36fe61711a9ca0f56 Mon Sep 17 00:00:00 2001 From: Eric Prestat Date: Sat, 22 Jul 2023 12:18:51 +0100 Subject: [PATCH 3/6] Fix typing --- lib/matplotlib/collections.pyi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/matplotlib/collections.pyi b/lib/matplotlib/collections.pyi index 7162c4687dfa..1aaa7ca7fd1c 100644 --- a/lib/matplotlib/collections.pyi +++ b/lib/matplotlib/collections.pyi @@ -180,6 +180,9 @@ class EllipseCollection(Collection): ] = ..., **kwargs ) -> None: ... + def set_widths(self, widths: ArrayLike) -> None: ... + def set_heights(self, heights: ArrayLike) -> None: ... + def set_angles(self, angles: ArrayLike) -> None: ... class PatchCollection(Collection): def __init__( From e4c5938989a0841f01e1688a7932d22d334e9e9c Mon Sep 17 00:00:00 2001 From: Eric Prestat Date: Sun, 23 Jul 2023 10:34:33 +0100 Subject: [PATCH 4/6] Use setters in constructor, add docstring to setters and improve tests --- lib/matplotlib/collections.py | 26 +++++++++++++++++------- lib/matplotlib/tests/test_collections.py | 8 ++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index c3380c278e37..92a3a522e9d2 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -1745,9 +1745,9 @@ def __init__(self, widths, heights, angles, *, units='points', **kwargs): Forwarded to `Collection`. """ super().__init__(**kwargs) - self._widths = 0.5 * np.asarray(widths).ravel() - self._heights = 0.5 * np.asarray(heights).ravel() - self._angles = np.deg2rad(angles).ravel() + self._set_widths(widths) + self._set_heights(heights) + self._set_angles(angles) self._units = units self.set_transform(transforms.IdentityTransform()) self._transforms = np.empty((0, 3, 3)) @@ -1795,16 +1795,28 @@ def _set_transforms(self): m[:2, 2:] = 0 self.set_transform(_affine(m)) - def set_widths(self, widths): + def _set_widths(self, widths): self._widths = 0.5 * np.asarray(widths).ravel() - self.stale = True - def set_angles(self, angles): + def _set_heights(self, heights): + self._heights = 0.5 * np.asarray(heights).ravel() + + def _set_angles(self, angles): self._angles = np.deg2rad(angles).ravel() + + def set_widths(self, widths): + """Set the lengths of the first axes (e.g., major axis lengths).""" + self._set_widths(widths) self.stale = True def set_heights(self, heights): - self._heights = 0.5 * np.asarray(heights).ravel() + """Set the lengths of second axes..""" + self._set_heights(heights) + self.stale = True + + def set_angles(self, angles): + """Set the angles of the first axes, degrees CCW from the x-axis.""" + self._set_angles(angles) self.stale = True @artist.allow_rasterization diff --git a/lib/matplotlib/tests/test_collections.py b/lib/matplotlib/tests/test_collections.py index 19ad4081715a..095ce76131a5 100644 --- a/lib/matplotlib/tests/test_collections.py +++ b/lib/matplotlib/tests/test_collections.py @@ -428,6 +428,10 @@ def test_EllipseCollection_setter(): offset_transform=ax.transData, ) + assert_array_almost_equal(ec._widths, np.array(widths).ravel() * 0.5) + assert_array_almost_equal(ec._heights, np.array(heights).ravel() * 0.5) + assert_array_almost_equal(ec._angles, np.deg2rad(angles).ravel()) + ax.add_collection(ec) ax.set_xlim(-2, 12) ax.set_ylim(-2, 12) @@ -438,6 +442,10 @@ def test_EllipseCollection_setter(): ec.set(widths=new_widths, heights=new_heights, angles=new_angles) + assert_array_almost_equal(ec._widths, np.array(new_widths).ravel() * 0.5) + assert_array_almost_equal(ec._heights, np.array(new_heights).ravel() * 0.5) + assert_array_almost_equal(ec._angles, np.deg2rad(new_angles).ravel()) + @image_comparison(['polycollection_close.png'], remove_text=True, style='mpl20') def test_polycollection_close(): From 45a6a6f2f0268207393d22b4431a5b78130f288c Mon Sep 17 00:00:00 2001 From: Eric Prestat Date: Sun, 28 Jan 2024 09:36:50 +0000 Subject: [PATCH 5/6] Add getters to EllipseColletion --- lib/matplotlib/collections.py | 16 ++++++++++++++-- lib/matplotlib/collections.pyi | 3 +++ lib/matplotlib/tests/test_collections.py | 12 ++++++++---- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index 92a3a522e9d2..b44dd4999ede 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -1805,20 +1805,32 @@ def _set_angles(self, angles): self._angles = np.deg2rad(angles).ravel() def set_widths(self, widths): - """Set the lengths of the first axes (e.g., major axis lengths).""" + """Set the lengths of the first axes (e.g., major axis).""" self._set_widths(widths) self.stale = True def set_heights(self, heights): - """Set the lengths of second axes..""" + """Set the lengths of second axes (e.g., minor axes).""" self._set_heights(heights) self.stale = True + def get_widths(self): + """Get the lengths of the first axes (e.g., major axis).""" + return self._widths * 2 + + def get_heights(self): + """Set the lengths of second axes (e.g., minor axes).""" + return self._heights * 2 + def set_angles(self, angles): """Set the angles of the first axes, degrees CCW from the x-axis.""" self._set_angles(angles) self.stale = True + def get_angles(self): + """Get the angles of the first axes, degrees CCW from the x-axis.""" + return np.rad2deg(self._angles) + @artist.allow_rasterization def draw(self, renderer): self._set_transforms() diff --git a/lib/matplotlib/collections.pyi b/lib/matplotlib/collections.pyi index 1aaa7ca7fd1c..65b50431b34b 100644 --- a/lib/matplotlib/collections.pyi +++ b/lib/matplotlib/collections.pyi @@ -181,8 +181,11 @@ class EllipseCollection(Collection): **kwargs ) -> None: ... def set_widths(self, widths: ArrayLike) -> None: ... + def get_widths(self) -> ArrayLike: ... def set_heights(self, heights: ArrayLike) -> None: ... + def get_heights(self) -> ArrayLike: ... def set_angles(self, angles: ArrayLike) -> None: ... + def get_angles(self) -> ArrayLike: ... class PatchCollection(Collection): def __init__( diff --git a/lib/matplotlib/tests/test_collections.py b/lib/matplotlib/tests/test_collections.py index 095ce76131a5..13eef30471f3 100644 --- a/lib/matplotlib/tests/test_collections.py +++ b/lib/matplotlib/tests/test_collections.py @@ -408,7 +408,7 @@ def test_EllipseCollection(): ax.autoscale_view() -def test_EllipseCollection_setter(): +def test_EllipseCollection_setter_getter(): # Test widths, heights and angle setter rng = np.random.default_rng(0) @@ -432,6 +432,10 @@ def test_EllipseCollection_setter(): assert_array_almost_equal(ec._heights, np.array(heights).ravel() * 0.5) assert_array_almost_equal(ec._angles, np.deg2rad(angles).ravel()) + assert_array_almost_equal(ec.get_widths(), widths) + assert_array_almost_equal(ec.get_heights(), heights) + assert_array_almost_equal(ec.get_angles(), angles) + ax.add_collection(ec) ax.set_xlim(-2, 12) ax.set_ylim(-2, 12) @@ -442,9 +446,9 @@ def test_EllipseCollection_setter(): ec.set(widths=new_widths, heights=new_heights, angles=new_angles) - assert_array_almost_equal(ec._widths, np.array(new_widths).ravel() * 0.5) - assert_array_almost_equal(ec._heights, np.array(new_heights).ravel() * 0.5) - assert_array_almost_equal(ec._angles, np.deg2rad(new_angles).ravel()) + assert_array_almost_equal(ec.get_widths(), new_widths.ravel()) + assert_array_almost_equal(ec.get_heights(), new_heights.ravel()) + assert_array_almost_equal(ec.get_angles(), new_angles.ravel()) @image_comparison(['polycollection_close.png'], remove_text=True, style='mpl20') From 729467c85a8661c50c5b845d2b9c5715208c68da Mon Sep 17 00:00:00 2001 From: Eric Prestat Date: Thu, 28 Mar 2024 14:42:25 +0000 Subject: [PATCH 6/6] Simplify `EllipseCollection` setter and tidy up typing --- lib/matplotlib/collections.py | 29 ++++++++++------------------- lib/matplotlib/collections.pyi | 4 ++-- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index b44dd4999ede..147ec634ca6f 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -1745,9 +1745,9 @@ def __init__(self, widths, heights, angles, *, units='points', **kwargs): Forwarded to `Collection`. """ super().__init__(**kwargs) - self._set_widths(widths) - self._set_heights(heights) - self._set_angles(angles) + self.set_widths(widths) + self.set_heights(heights) + self.set_angles(angles) self._units = units self.set_transform(transforms.IdentityTransform()) self._transforms = np.empty((0, 3, 3)) @@ -1795,23 +1795,19 @@ def _set_transforms(self): m[:2, 2:] = 0 self.set_transform(_affine(m)) - def _set_widths(self, widths): - self._widths = 0.5 * np.asarray(widths).ravel() - - def _set_heights(self, heights): - self._heights = 0.5 * np.asarray(heights).ravel() - - def _set_angles(self, angles): - self._angles = np.deg2rad(angles).ravel() - def set_widths(self, widths): """Set the lengths of the first axes (e.g., major axis).""" - self._set_widths(widths) + self._widths = 0.5 * np.asarray(widths).ravel() self.stale = True def set_heights(self, heights): """Set the lengths of second axes (e.g., minor axes).""" - self._set_heights(heights) + self._heights = 0.5 * np.asarray(heights).ravel() + self.stale = True + + def set_angles(self, angles): + """Set the angles of the first axes, degrees CCW from the x-axis.""" + self._angles = np.deg2rad(angles).ravel() self.stale = True def get_widths(self): @@ -1822,11 +1818,6 @@ def get_heights(self): """Set the lengths of second axes (e.g., minor axes).""" return self._heights * 2 - def set_angles(self, angles): - """Set the angles of the first axes, degrees CCW from the x-axis.""" - self._set_angles(angles) - self.stale = True - def get_angles(self): """Get the angles of the first axes, degrees CCW from the x-axis.""" return np.rad2deg(self._angles) diff --git a/lib/matplotlib/collections.pyi b/lib/matplotlib/collections.pyi index 65b50431b34b..e4c46229517f 100644 --- a/lib/matplotlib/collections.pyi +++ b/lib/matplotlib/collections.pyi @@ -181,10 +181,10 @@ class EllipseCollection(Collection): **kwargs ) -> None: ... def set_widths(self, widths: ArrayLike) -> None: ... - def get_widths(self) -> ArrayLike: ... def set_heights(self, heights: ArrayLike) -> None: ... - def get_heights(self) -> ArrayLike: ... def set_angles(self, angles: ArrayLike) -> None: ... + def get_widths(self) -> ArrayLike: ... + def get_heights(self) -> ArrayLike: ... def get_angles(self) -> ArrayLike: ... class PatchCollection(Collection): 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