From eeed6fcdbbe6b23597c35dee567284aa399046a8 Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Thu, 27 Apr 2023 13:43:21 +0200 Subject: [PATCH 01/33] Adding ellipse_arrow.py example and fix #25477 --- .../shapes_and_collections/ellipse_arrow.py | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 galleries/examples/shapes_and_collections/ellipse_arrow.py diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py new file mode 100644 index 000000000000..9d4ef4483aa6 --- /dev/null +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -0,0 +1,46 @@ +""" +============ +Ellipse with arrow Demo +============ + +Draw an ellipses with an arrow showing rotation direction. Compare this +to the :doc:`Ellipse collection example +`. +""" + +import matplotlib.pyplot as plt +import numpy as np + +# Define start position of ellipse +xVec = 0.5 + 0.5j +yVec = 0.2 + 0.5j + +sampling = 101 +n = np.linspace(0, sampling, sampling) + +# Calculate ellipse data points +x = np.real(xVec * np.exp(1j * 2 * np.pi * n / sampling)) +y = np.real(yVec * np.exp(1j * 2 * np.pi * n / sampling)) + +# Draw ellipse +fig, ax = plt.subplots(1, 1, subplot_kw={"aspect": "equal"}) +ax.plot(x, y) + +# Calculate arrow position and orientation +dx = x[-1] - x[-2] +dy = y[-1] - y[-2] +ax.arrow(x=x[-1], y=y[-1], dx=dx, dy=dy, head_width=0.05) + +ax.set_xlim((-1, 1)) +ax.set_ylim((-1, 1)) +plt.show() + +# %% +# +# .. admonition:: References +# +# The use of the following functions, methods, classes and modules is shown +# in this example: +# +# - `matplotlib.patches` +# - `matplotlib.patches.Ellipse` From e16c81df8d1e15df1ed560d371644af3b7b6123b Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Thu, 27 Apr 2023 19:34:21 +0200 Subject: [PATCH 02/33] adapt the = lines to fix docu build test --- galleries/examples/shapes_and_collections/ellipse_arrow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index 9d4ef4483aa6..503c71ed89ad 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -1,7 +1,7 @@ """ -============ +======================= Ellipse with arrow Demo -============ +======================= Draw an ellipses with an arrow showing rotation direction. Compare this to the :doc:`Ellipse collection example From f8dc66f2abe15755127a12ff35b443ea772b491c Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Thu, 27 Apr 2023 20:46:03 +0200 Subject: [PATCH 03/33] use plt.subplot() --- galleries/examples/shapes_and_collections/ellipse_arrow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index 503c71ed89ad..670029830975 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -23,7 +23,7 @@ y = np.real(yVec * np.exp(1j * 2 * np.pi * n / sampling)) # Draw ellipse -fig, ax = plt.subplots(1, 1, subplot_kw={"aspect": "equal"}) +ax = plt.subplot() ax.plot(x, y) # Calculate arrow position and orientation From 4ae516ecd65f4bb8db7a3ef523ad9781994a5088 Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Sat, 29 Apr 2023 21:20:09 +0200 Subject: [PATCH 04/33] Now the patches.Ellipse is used for the plot and a marker ">" at the end point position of the ellipse minor axis rotated by the transform.Affine2D method. --- .../shapes_and_collections/ellipse_arrow.py | 96 ++++++++++++++----- 1 file changed, 74 insertions(+), 22 deletions(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index 670029830975..3f3d2cd1d085 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -1,40 +1,92 @@ """ -======================= -Ellipse with arrow Demo -======================= +=================================== +Ellipse with orientation arrow Demo +=================================== -Draw an ellipses with an arrow showing rotation direction. Compare this -to the :doc:`Ellipse collection example +This demo shows how to draw an ellipse with an orientation arrow. +Compare this to the :doc:`Ellipse collection example `. """ +# Import of namespaces import matplotlib.pyplot as plt +from matplotlib.patches import Ellipse +from matplotlib.markers import MarkerStyle +from matplotlib.transforms import Affine2D + import numpy as np +from typing import Tuple + + +def getMinorMajor(ellipse: Ellipse) -> Tuple[list, list]: + """Calculates the end points of minor and major axis of an ellipse. + + Args: + ellipse (Ellipse): Ellipse patch. -# Define start position of ellipse -xVec = 0.5 + 0.5j -yVec = 0.2 + 0.5j + Returns: + Tuple[list, list]: Coordinates of minor end points and major end points. + """ + # Calculate the endpoints of the minor axis + x0_minor = ellipse.center[0] - ellipse.height / 2 * np.sin( + np.deg2rad(ellipse.angle) + ) + y0_minor = ellipse.center[1] + ellipse.height / 2 * np.cos( + np.deg2rad(ellipse.angle) + ) + x1_minor = ellipse.center[0] + ellipse.height / 2 * np.sin( + np.deg2rad(ellipse.angle) + ) + y1_minor = ellipse.center[1] - ellipse.height / 2 * np.cos( + np.deg2rad(ellipse.angle) + ) -sampling = 101 -n = np.linspace(0, sampling, sampling) + # Calculate the endpoints of the major axis + x0_major = ellipse.center[0] - ellipse.width / 2 * np.cos(np.deg2rad(ellipse.angle)) + y0_major = ellipse.center[1] - ellipse.width / 2 * np.sin(np.deg2rad(ellipse.angle)) + x1_major = ellipse.center[0] + ellipse.width / 2 * np.cos(np.deg2rad(ellipse.angle)) + y1_major = ellipse.center[1] + ellipse.width / 2 * np.sin(np.deg2rad(ellipse.angle)) + return [(x0_minor, y0_minor), (x1_minor, y1_minor)], [ + (x0_major, y0_major), + (x1_major, y1_major), + ] -# Calculate ellipse data points -x = np.real(xVec * np.exp(1j * 2 * np.pi * n / sampling)) -y = np.real(yVec * np.exp(1j * 2 * np.pi * n / sampling)) -# Draw ellipse -ax = plt.subplot() -ax.plot(x, y) +# Define the ellipse +center = (2, 4) +width = 30 +height = 20 +angle = 35 +ellipse = Ellipse( + xy=center, + width=width, + height=height, + angle=angle, + facecolor="none", + edgecolor="b", +) -# Calculate arrow position and orientation -dx = x[-1] - x[-2] -dy = y[-1] - y[-2] -ax.arrow(x=x[-1], y=y[-1], dx=dx, dy=dy, head_width=0.05) +minor, major = getMinorMajor(ellipse) + +# Create a figure and axis +fig, ax = plt.subplots(1, 1, subplot_kw={"aspect": "equal"}) + +# Add the ellipse patch to the axis +ax.add_patch(ellipse) + +# Plot a arrow marker at the end point of minor axis +t = Affine2D().rotate_deg(angle) +ax.plot( + minor[0][0], + minor[0][1], + color="b", + marker=MarkerStyle(">", "full", t), + markersize=10, +) -ax.set_xlim((-1, 1)) -ax.set_ylim((-1, 1)) plt.show() + # %% # # .. admonition:: References From 0005c7e24b3a697acee97095fe952a79751cf029 Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Sat, 29 Apr 2023 21:39:35 +0200 Subject: [PATCH 05/33] changed function docstring to numpy style --- .../shapes_and_collections/ellipse_arrow.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index 3f3d2cd1d085..39e21ea3db62 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -15,17 +15,22 @@ from matplotlib.transforms import Affine2D import numpy as np + from typing import Tuple def getMinorMajor(ellipse: Ellipse) -> Tuple[list, list]: - """Calculates the end points of minor and major axis of an ellipse. + """ + Calculates the end points of minor and major axis of an ellipse. - Args: - ellipse (Ellipse): Ellipse patch. + Parameters + ---------- + ellipse : ~matplotlib.patches.Ellipse + Ellipse patch. - Returns: - Tuple[list, list]: Coordinates of minor end points and major end points. + Returns + ------- + ~typing.Tuple[list, list] """ # Calculate the endpoints of the minor axis x0_minor = ellipse.center[0] - ellipse.height / 2 * np.sin( From 944a513a7340bc1f06779213f90bf21e139d6eba Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Sat, 29 Apr 2023 23:11:49 +0200 Subject: [PATCH 06/33] fix flake8 build fail --- .../examples/shapes_and_collections/ellipse_arrow.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index 39e21ea3db62..ec28edbbd5fe 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -18,6 +18,16 @@ from typing import Tuple +# %% +# +# A method to calculate the end points of the ellipse major, minor axis +# """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +# +# Calculates the minor axis and major axis end points of the ellipse. +# It needs the ellipse parameter like widht, height, angle. +# The output are 2 lists of 2 xy coordinates +# (minor((x0, y0), (x1, y1)), major((x0, y0), (x1, y1))). + def getMinorMajor(ellipse: Ellipse) -> Tuple[list, list]: """ From 8acae1eed5403a870c7b0b47b4bdaf2a92ab0d04 Mon Sep 17 00:00:00 2001 From: Photoniker <17592823+photoniker@users.noreply.github.com> Date: Sat, 29 Apr 2023 23:21:15 +0200 Subject: [PATCH 07/33] Update ellipse_arrow.py --- galleries/examples/shapes_and_collections/ellipse_arrow.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index ec28edbbd5fe..9c00b9ba105a 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -23,9 +23,9 @@ # A method to calculate the end points of the ellipse major, minor axis # """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" # -# Calculates the minor axis and major axis end points of the ellipse. -# It needs the ellipse parameter like widht, height, angle. -# The output are 2 lists of 2 xy coordinates +# Calculates the minor axis and major axis end points of the ellipse. +# It needs the ellipse parameter like widht, height, angle. +# The output are 2 lists of 2 xy coordinates # (minor((x0, y0), (x1, y1)), major((x0, y0), (x1, y1))). From 74c4480171ca63eaaffee2e282c89bb3575d73fc Mon Sep 17 00:00:00 2001 From: Photoniker <17592823+photoniker@users.noreply.github.com> Date: Sat, 29 Apr 2023 23:24:42 +0200 Subject: [PATCH 08/33] Update ellipse_arrow.py --- galleries/examples/shapes_and_collections/ellipse_arrow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index 9c00b9ba105a..8c40cb0a7107 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -24,7 +24,7 @@ # """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" # # Calculates the minor axis and major axis end points of the ellipse. -# It needs the ellipse parameter like widht, height, angle. +# It needs the ellipse parameter like width, height, angle. # The output are 2 lists of 2 xy coordinates # (minor((x0, y0), (x1, y1)), major((x0, y0), (x1, y1))). From 02865ef076ad3d72626581aeaf01d3edecb83e9a Mon Sep 17 00:00:00 2001 From: Photoniker <17592823+photoniker@users.noreply.github.com> Date: Sun, 30 Apr 2023 05:02:29 +0200 Subject: [PATCH 09/33] Update ellipse_arrow.py --- galleries/examples/shapes_and_collections/ellipse_arrow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index 8c40cb0a7107..e2e5a6d69734 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -3,7 +3,7 @@ Ellipse with orientation arrow Demo =================================== -This demo shows how to draw an ellipse with an orientation arrow. +This demo shows how to draw an ellipse with an orientation arrow (clockwise or counterclockwise). Compare this to the :doc:`Ellipse collection example `. """ From 15a84c1c938e92294feba56af50a7b821de5f92a Mon Sep 17 00:00:00 2001 From: Photoniker <17592823+photoniker@users.noreply.github.com> Date: Sun, 30 Apr 2023 05:07:02 +0200 Subject: [PATCH 10/33] Update ellipse_arrow.py --- galleries/examples/shapes_and_collections/ellipse_arrow.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index e2e5a6d69734..0f63717292f2 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -3,7 +3,8 @@ Ellipse with orientation arrow Demo =================================== -This demo shows how to draw an ellipse with an orientation arrow (clockwise or counterclockwise). +This demo shows how to draw an ellipse with +an orientation arrow (clockwise or counterclockwise). Compare this to the :doc:`Ellipse collection example `. """ From f9fd86811e918c4faca34c5998723fb541152990 Mon Sep 17 00:00:00 2001 From: Photoniker <17592823+photoniker@users.noreply.github.com> Date: Sun, 30 Apr 2023 05:10:58 +0200 Subject: [PATCH 11/33] Update ellipse_arrow.py --- galleries/examples/shapes_and_collections/ellipse_arrow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index 0f63717292f2..d310dde816d0 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -3,7 +3,7 @@ Ellipse with orientation arrow Demo =================================== -This demo shows how to draw an ellipse with +This demo shows how to draw an ellipse with an orientation arrow (clockwise or counterclockwise). Compare this to the :doc:`Ellipse collection example `. From e3ad826e292d14fbd62eea0299fcc26165d12647 Mon Sep 17 00:00:00 2001 From: Photoniker <17592823+photoniker@users.noreply.github.com> Date: Sun, 30 Apr 2023 05:29:36 +0200 Subject: [PATCH 12/33] Update ellipse_arrow.py --- galleries/examples/shapes_and_collections/ellipse_arrow.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index d310dde816d0..a85246403bd2 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -10,12 +10,12 @@ """ # Import of namespaces +import numpy as np import matplotlib.pyplot as plt + +from matplotlib.transforms import Affine2D from matplotlib.patches import Ellipse from matplotlib.markers import MarkerStyle -from matplotlib.transforms import Affine2D - -import numpy as np from typing import Tuple From e12a72a7333a486c32d7af24d66bfe635e61263b Mon Sep 17 00:00:00 2001 From: Photoniker <17592823+photoniker@users.noreply.github.com> Date: Sun, 30 Apr 2023 05:47:22 +0200 Subject: [PATCH 13/33] Update ellipse_arrow.py --- .../examples/shapes_and_collections/ellipse_arrow.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index a85246403bd2..6932f72d2888 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -9,15 +9,14 @@ `. """ -# Import of namespaces -import numpy as np +from typing import Tuple + import matplotlib.pyplot as plt +import numpy as np -from matplotlib.transforms import Affine2D -from matplotlib.patches import Ellipse from matplotlib.markers import MarkerStyle - -from typing import Tuple +from matplotlib.patches import Ellipse +from matplotlib.transforms import Affine2D # %% # From 303f957d01d846b517e678ef6219eb9c5f4effbd Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Sun, 30 Apr 2023 22:11:50 +0200 Subject: [PATCH 14/33] added get_vertices and get_co_vertices methods the Ellipse --- .../shapes_and_collections/ellipse_arrow.py | 125 +++++++++--------- lib/matplotlib/patches.py | 24 ++++ lib/matplotlib/tests/test_patches.py | 22 +++ 3 files changed, 106 insertions(+), 65 deletions(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index 6932f72d2888..c444de6e7c29 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -1,6 +1,6 @@ """ =================================== -Ellipse with orientation arrow Demo +Ellipse with orientation arrow demo =================================== This demo shows how to draw an ellipse with @@ -9,98 +9,93 @@ `. """ -from typing import Tuple - import matplotlib.pyplot as plt -import numpy as np - from matplotlib.markers import MarkerStyle from matplotlib.patches import Ellipse from matplotlib.transforms import Affine2D -# %% -# -# A method to calculate the end points of the ellipse major, minor axis -# """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -# -# Calculates the minor axis and major axis end points of the ellipse. -# It needs the ellipse parameter like width, height, angle. -# The output are 2 lists of 2 xy coordinates -# (minor((x0, y0), (x1, y1)), major((x0, y0), (x1, y1))). - - -def getMinorMajor(ellipse: Ellipse) -> Tuple[list, list]: - """ - Calculates the end points of minor and major axis of an ellipse. - - Parameters - ---------- - ellipse : ~matplotlib.patches.Ellipse - Ellipse patch. - - Returns - ------- - ~typing.Tuple[list, list] - """ - # Calculate the endpoints of the minor axis - x0_minor = ellipse.center[0] - ellipse.height / 2 * np.sin( - np.deg2rad(ellipse.angle) - ) - y0_minor = ellipse.center[1] + ellipse.height / 2 * np.cos( - np.deg2rad(ellipse.angle) - ) - x1_minor = ellipse.center[0] + ellipse.height / 2 * np.sin( - np.deg2rad(ellipse.angle) - ) - y1_minor = ellipse.center[1] - ellipse.height / 2 * np.cos( - np.deg2rad(ellipse.angle) - ) - - # Calculate the endpoints of the major axis - x0_major = ellipse.center[0] - ellipse.width / 2 * np.cos(np.deg2rad(ellipse.angle)) - y0_major = ellipse.center[1] - ellipse.width / 2 * np.sin(np.deg2rad(ellipse.angle)) - x1_major = ellipse.center[0] + ellipse.width / 2 * np.cos(np.deg2rad(ellipse.angle)) - y1_major = ellipse.center[1] + ellipse.width / 2 * np.sin(np.deg2rad(ellipse.angle)) - return [(x0_minor, y0_minor), (x1_minor, y1_minor)], [ - (x0_major, y0_major), - (x1_major, y1_major), - ] - - -# Define the ellipse + +# Create a figure and axis +fig, ax = plt.subplots(1, 1, subplot_kw={"aspect": "equal"}) + +# Define an ellipse clockwise center = (2, 4) width = 30 height = 20 angle = 35 -ellipse = Ellipse( +ellipse_clockwise = Ellipse( xy=center, width=width, height=height, angle=angle, facecolor="none", edgecolor="b", + label="clockwise" ) -minor, major = getMinorMajor(ellipse) - -# Create a figure and axis -fig, ax = plt.subplots(1, 1, subplot_kw={"aspect": "equal"}) +# Get position of vertex for arrow marker +vertices = ellipse_clockwise.get_co_vertices() # Add the ellipse patch to the axis -ax.add_patch(ellipse) +ax.add_patch(ellipse_clockwise) # Plot a arrow marker at the end point of minor axis -t = Affine2D().rotate_deg(angle) +t = Affine2D().rotate_deg(ellipse_clockwise.angle) ax.plot( - minor[0][0], - minor[0][1], + vertices[0][0], + vertices[0][1], color="b", marker=MarkerStyle(">", "full", t), - markersize=10, + markersize=10 ) +# Define an second ellipse counterclockwise +center = (2, 4) +width = 30 +height = 15 +angle = -20 +ellipse_counterclockwise = Ellipse( + xy=center, + width=width, + height=height, + angle=angle, + facecolor="none", + edgecolor="g", + label="counterclockwise" +) + +# Add the ellipse patch to the axis +ax.add_patch(ellipse_counterclockwise) + +# Get position of vertex for arrow marker +vertices = ellipse_counterclockwise.get_co_vertices() + +# Plot a arrow marker at the end point of minor axis +t = Affine2D().rotate_deg(ellipse_counterclockwise.angle) +ax.plot( + vertices[0][0], + vertices[0][1], + color="g", + marker=MarkerStyle("<", "full", t), + markersize=10 +) + + +plt.legend() plt.show() +center = (2, 4) +width = 30 +height = 20 +angle = 35 +ellipse = Ellipse( + xy=center, + width=width, + height=height, + angle=angle +) +print(ellipse.get_vertices()) +print(ellipse.get_co_vertices()) # %% # diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index 245bb7b777c8..665cf5b9f15f 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -1654,6 +1654,30 @@ def get_corners(self): return self.get_patch_transform().transform( [(-1, -1), (1, -1), (1, 1), (-1, 1)]) + def get_vertices(self): + """ + Return the left and right vertex coordinates of the ellipse. + + The definition can be found `here`_ + """ + x0 = self._center[0] - self._width / 2 * np.cos(np.deg2rad(self._angle)) + y0 = self._center[1] - self._width / 2 * np.sin(np.deg2rad(self._angle)) + x1 = self._center[0] + self._width / 2 * np.cos(np.deg2rad(self._angle)) + y1 = self._center[1] + self._width / 2 * np.sin(np.deg2rad(self._angle)) + return [(x0, y0), (x1, y1)] + + def get_co_vertices(self): + """ + Return the left and right co-vertex coordinates of the ellipse. + + The definition can be found `here`_ + """ + x0 = self._center[0] - self._height / 2 * np.sin(np.deg2rad(self._angle)) + y0 = self._center[1] + self._height / 2 * np.cos(np.deg2rad(self._angle)) + x1 = self._center[0] + self._height / 2 * np.sin(np.deg2rad(self._angle)) + y1 = self._center[1] - self._height / 2 * np.cos(np.deg2rad(self._angle)) + return [(x0, y0), (x1, y1)] + class Annulus(Patch): """ diff --git a/lib/matplotlib/tests/test_patches.py b/lib/matplotlib/tests/test_patches.py index b9e1db32d419..f72bce85ec05 100644 --- a/lib/matplotlib/tests/test_patches.py +++ b/lib/matplotlib/tests/test_patches.py @@ -104,6 +104,28 @@ def test_corner_center(): assert_almost_equal(ellipse.get_corners(), corners_rot) +def test_ellipse_vertices(): + center = (2, 4) + width = 30 + height = 20 + angle = 35 + ellipse = Ellipse(xy=center, width=width, height=height, angle=angle) + assert_almost_equal( + ellipse.get_vertices(), + [ + (-10.287280664334878, -4.60364654526569), + (14.287280664334878, 12.60364654526569), + ], + ) + assert_almost_equal( + ellipse.get_co_vertices(), + [ + (-3.7357643635104605, 12.191520442889917), + (7.7357643635104605, -4.191520442889917), + ], + ) + + def test_rotate_rect(): loc = np.asarray([1.0, 2.0]) width = 2 From 3df0bbb0368432a83fa4b95140926afa6f7c9ac8 Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Sun, 30 Apr 2023 22:14:54 +0200 Subject: [PATCH 15/33] deleted blank lines --- lib/matplotlib/patches.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index 665cf5b9f15f..2d7707fdde8c 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -1665,7 +1665,7 @@ def get_vertices(self): x1 = self._center[0] + self._width / 2 * np.cos(np.deg2rad(self._angle)) y1 = self._center[1] + self._width / 2 * np.sin(np.deg2rad(self._angle)) return [(x0, y0), (x1, y1)] - + def get_co_vertices(self): """ Return the left and right co-vertex coordinates of the ellipse. From bbf76e7d0627853164692203440939312af8f39d Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Sun, 30 Apr 2023 22:18:29 +0200 Subject: [PATCH 16/33] sorry, some more whitespaces in blank line --- lib/matplotlib/patches.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index 2d7707fdde8c..2c7ba8b0d22a 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -1669,7 +1669,7 @@ def get_vertices(self): def get_co_vertices(self): """ Return the left and right co-vertex coordinates of the ellipse. - + The definition can be found `here`_ """ x0 = self._center[0] - self._height / 2 * np.sin(np.deg2rad(self._angle)) From f07471313a4342ab30246c9dcb19ea00288c4585 Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Mon, 1 May 2023 14:29:02 +0200 Subject: [PATCH 17/33] added entries in stubs, resolve docu issues --- .../shapes_and_collections/ellipse_arrow.py | 71 +++---------------- lib/matplotlib/patches.py | 4 +- lib/matplotlib/patches.pyi | 3 + 3 files changed, 15 insertions(+), 63 deletions(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index c444de6e7c29..004256d30e79 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -16,31 +16,26 @@ # Create a figure and axis -fig, ax = plt.subplots(1, 1, subplot_kw={"aspect": "equal"}) +fig, ax = plt.subplots(subplot_kw={"aspect": "equal"}) # Define an ellipse clockwise -center = (2, 4) -width = 30 -height = 20 -angle = 35 -ellipse_clockwise = Ellipse( +center=(2, 4) +width=30 +height=20 +angle=35 +ellipse = Ellipse( xy=center, width=width, height=height, angle=angle, facecolor="none", - edgecolor="b", - label="clockwise" + edgecolor="b" ) - -# Get position of vertex for arrow marker -vertices = ellipse_clockwise.get_co_vertices() - -# Add the ellipse patch to the axis -ax.add_patch(ellipse_clockwise) +ax.add_patch(ellipse) # Plot a arrow marker at the end point of minor axis -t = Affine2D().rotate_deg(ellipse_clockwise.angle) +vertices = ellipse.get_co_vertices() +t = Affine2D().rotate_deg(ellipse.angle) ax.plot( vertices[0][0], vertices[0][1], @@ -49,54 +44,8 @@ markersize=10 ) -# Define an second ellipse counterclockwise -center = (2, 4) -width = 30 -height = 15 -angle = -20 -ellipse_counterclockwise = Ellipse( - xy=center, - width=width, - height=height, - angle=angle, - facecolor="none", - edgecolor="g", - label="counterclockwise" -) - -# Add the ellipse patch to the axis -ax.add_patch(ellipse_counterclockwise) - -# Get position of vertex for arrow marker -vertices = ellipse_counterclockwise.get_co_vertices() - -# Plot a arrow marker at the end point of minor axis -t = Affine2D().rotate_deg(ellipse_counterclockwise.angle) -ax.plot( - vertices[0][0], - vertices[0][1], - color="g", - marker=MarkerStyle("<", "full", t), - markersize=10 -) - - -plt.legend() plt.show() -center = (2, 4) -width = 30 -height = 20 -angle = 35 -ellipse = Ellipse( - xy=center, - width=width, - height=height, - angle=angle -) -print(ellipse.get_vertices()) -print(ellipse.get_co_vertices()) - # %% # # .. admonition:: References diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index 2c7ba8b0d22a..faf070aadcf1 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -1658,7 +1658,7 @@ def get_vertices(self): """ Return the left and right vertex coordinates of the ellipse. - The definition can be found `here`_ + The definition can be found `here `_ """ x0 = self._center[0] - self._width / 2 * np.cos(np.deg2rad(self._angle)) y0 = self._center[1] - self._width / 2 * np.sin(np.deg2rad(self._angle)) @@ -1670,7 +1670,7 @@ def get_co_vertices(self): """ Return the left and right co-vertex coordinates of the ellipse. - The definition can be found `here`_ + The definition can be found `here `_ """ x0 = self._center[0] - self._height / 2 * np.sin(np.deg2rad(self._angle)) y0 = self._center[1] + self._height / 2 * np.cos(np.deg2rad(self._angle)) diff --git a/lib/matplotlib/patches.pyi b/lib/matplotlib/patches.pyi index 1e70a1efc3be..dcd8b638749f 100644 --- a/lib/matplotlib/patches.pyi +++ b/lib/matplotlib/patches.pyi @@ -258,6 +258,9 @@ class Ellipse(Patch): angle = property(get_angle, set_angle) def get_corners(self) -> np.ndarray: ... + + def get_vertices(self) -> list[float, float]: ... + def get_co_vertices(self) -> list[float, float]: ... class Annulus(Patch): a: float From 2578cd97b5449e7d025f1f814ed2c2f5b447d45b Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Mon, 1 May 2023 14:34:38 +0200 Subject: [PATCH 18/33] resolve flake8 --- .../examples/shapes_and_collections/ellipse_arrow.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index 004256d30e79..3b53beca7d4a 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -19,10 +19,10 @@ fig, ax = plt.subplots(subplot_kw={"aspect": "equal"}) # Define an ellipse clockwise -center=(2, 4) -width=30 -height=20 -angle=35 +center = (2, 4) +width = 30 +height = 20 +angle = 35 ellipse = Ellipse( xy=center, width=width, @@ -43,6 +43,7 @@ marker=MarkerStyle(">", "full", t), markersize=10 ) +# Note: To reverse the orientation arrow, switch the marker type from > to <. plt.show() From 0b492d18fcd7d84fd902cdcc926c62af1813c95b Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Mon, 1 May 2023 14:37:04 +0200 Subject: [PATCH 19/33] resolve return values --- lib/matplotlib/patches.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/patches.pyi b/lib/matplotlib/patches.pyi index dcd8b638749f..6f1a9b45a2db 100644 --- a/lib/matplotlib/patches.pyi +++ b/lib/matplotlib/patches.pyi @@ -259,8 +259,8 @@ class Ellipse(Patch): def get_corners(self) -> np.ndarray: ... - def get_vertices(self) -> list[float, float]: ... - def get_co_vertices(self) -> list[float, float]: ... + def get_vertices(self) -> list[tuple[float, float], tuple[float, float]]: ... + def get_co_vertices(self) -> list[tuple[float, float], tuple[float, float]]: ... class Annulus(Patch): a: float From 03869252a557bf54861090b9efe31866ed1ebbf2 Mon Sep 17 00:00:00 2001 From: Photoniker <17592823+photoniker@users.noreply.github.com> Date: Mon, 1 May 2023 14:40:50 +0200 Subject: [PATCH 20/33] Update patches.pyi --- lib/matplotlib/patches.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/patches.pyi b/lib/matplotlib/patches.pyi index 6f1a9b45a2db..17ce9d6b21ff 100644 --- a/lib/matplotlib/patches.pyi +++ b/lib/matplotlib/patches.pyi @@ -259,8 +259,8 @@ class Ellipse(Patch): def get_corners(self) -> np.ndarray: ... - def get_vertices(self) -> list[tuple[float, float], tuple[float, float]]: ... - def get_co_vertices(self) -> list[tuple[float, float], tuple[float, float]]: ... + def get_vertices(self) -> list[tuple[float, float]]: ... + def get_co_vertices(self) -> list[tuple[float, float]]: ... class Annulus(Patch): a: float From f23854ddfded14dce3d094dd3db677481a239696 Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Mon, 1 May 2023 14:46:45 +0200 Subject: [PATCH 21/33] overseen some whitespaces, sorry --- lib/matplotlib/patches.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/patches.pyi b/lib/matplotlib/patches.pyi index 6f1a9b45a2db..fd0262c4f4a0 100644 --- a/lib/matplotlib/patches.pyi +++ b/lib/matplotlib/patches.pyi @@ -258,7 +258,7 @@ class Ellipse(Patch): angle = property(get_angle, set_angle) def get_corners(self) -> np.ndarray: ... - + def get_vertices(self) -> list[tuple[float, float], tuple[float, float]]: ... def get_co_vertices(self) -> list[tuple[float, float], tuple[float, float]]: ... From 135d7cb1387d61dae9b1696b2dd3f21217d02d1d Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Mon, 1 May 2023 14:55:33 +0200 Subject: [PATCH 22/33] soved isort fail. How to solve the subs fail? --- galleries/examples/shapes_and_collections/ellipse_arrow.py | 2 +- lib/matplotlib/patches.pyi | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index 3b53beca7d4a..09f527fcfa55 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -10,11 +10,11 @@ """ import matplotlib.pyplot as plt + from matplotlib.markers import MarkerStyle from matplotlib.patches import Ellipse from matplotlib.transforms import Affine2D - # Create a figure and axis fig, ax = plt.subplots(subplot_kw={"aspect": "equal"}) diff --git a/lib/matplotlib/patches.pyi b/lib/matplotlib/patches.pyi index e9302563083c..6efb9e3347fc 100644 --- a/lib/matplotlib/patches.pyi +++ b/lib/matplotlib/patches.pyi @@ -259,8 +259,8 @@ class Ellipse(Patch): def get_corners(self) -> np.ndarray: ... - def get_vertices(self) -> list[tuple[float, float]]: ... - def get_co_vertices(self) -> list[tuple[float, float]]: ... + def get_vertices(self) -> tuple[float, float]: ... + def get_co_vertices(self) -> tuple[float, float]: ... class Annulus(Patch): From 9776379ac9f87389f0dcedda1f7ed79d44564e39 Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Mon, 1 May 2023 19:52:14 +0200 Subject: [PATCH 23/33] added some more unittest, just in case... --- lib/matplotlib/tests/test_patches.py | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/lib/matplotlib/tests/test_patches.py b/lib/matplotlib/tests/test_patches.py index f72bce85ec05..90332e5573b7 100644 --- a/lib/matplotlib/tests/test_patches.py +++ b/lib/matplotlib/tests/test_patches.py @@ -125,6 +125,42 @@ def test_ellipse_vertices(): ], ) + assert_almost_equal( + Ellipse(xy=(0, 0), width=0, height=0, angle=0).get_vertices(), + [(0.0, 0.0), (0.0, 0.0)], + ) + assert_almost_equal( + Ellipse(xy=(0, 0), width=0, height=0, angle=0).get_co_vertices(), + [(0.0, 0.0), (0.0, 0.0)], + ) + + assert_almost_equal( + Ellipse(xy=(0, 0), width=1, height=0, angle=0).get_vertices(), + [(-0.5, 0.0), (0.5, 0.0)], + ) + assert_almost_equal( + Ellipse(xy=(0, 0), width=1, height=0, angle=0).get_co_vertices(), + [(0.0, 0.0), (0.0, 0.0)], + ) + + assert_almost_equal( + Ellipse(xy=(0, 0), width=1, height=1, angle=0).get_vertices(), + [(-0.5, 0.0), (0.5, 0.0)], + ) + assert_almost_equal( + Ellipse(xy=(0, 0), width=1, height=1, angle=0).get_co_vertices(), + [(0.0, 0.5), (0.0, -0.5)], + ) + + assert_almost_equal( + Ellipse(xy=(0, 0), width=1, height=0.5, angle=90).get_vertices(), + [(0.0, -0.5), (0.0, 0.5)], + ) + assert_almost_equal( + Ellipse(xy=(0, 0), width=1, height=0.5, angle=90).get_co_vertices(), + [(-0.25, 0.0), (0.25, 0.0)], + ) + def test_rotate_rect(): loc = np.asarray([1.0, 2.0]) From 801031f7565bcb2d6b66d46510018621110e6c59 Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Tue, 2 May 2023 21:14:32 +0200 Subject: [PATCH 24/33] adapted unittest --- lib/matplotlib/tests/test_patches.py | 79 +++++++++++++--------------- 1 file changed, 36 insertions(+), 43 deletions(-) diff --git a/lib/matplotlib/tests/test_patches.py b/lib/matplotlib/tests/test_patches.py index 90332e5573b7..ac26b75231f7 100644 --- a/lib/matplotlib/tests/test_patches.py +++ b/lib/matplotlib/tests/test_patches.py @@ -105,61 +105,54 @@ def test_corner_center(): def test_ellipse_vertices(): - center = (2, 4) - width = 30 - height = 20 - angle = 35 - ellipse = Ellipse(xy=center, width=width, height=height, angle=angle) + # expect 0 for 0 ellipse widht, height + ellipse = Ellipse(xy=(0, 0), width=0, height=0, angle=0) assert_almost_equal( ellipse.get_vertices(), - [ - (-10.287280664334878, -4.60364654526569), - (14.287280664334878, 12.60364654526569), - ], - ) - assert_almost_equal( - ellipse.get_co_vertices(), - [ - (-3.7357643635104605, 12.191520442889917), - (7.7357643635104605, -4.191520442889917), - ], - ) - - assert_almost_equal( - Ellipse(xy=(0, 0), width=0, height=0, angle=0).get_vertices(), [(0.0, 0.0), (0.0, 0.0)], ) assert_almost_equal( - Ellipse(xy=(0, 0), width=0, height=0, angle=0).get_co_vertices(), - [(0.0, 0.0), (0.0, 0.0)], - ) - - assert_almost_equal( - Ellipse(xy=(0, 0), width=1, height=0, angle=0).get_vertices(), - [(-0.5, 0.0), (0.5, 0.0)], - ) - assert_almost_equal( - Ellipse(xy=(0, 0), width=1, height=0, angle=0).get_co_vertices(), + ellipse.get_co_vertices(), [(0.0, 0.0), (0.0, 0.0)], ) + ellipse = Ellipse(xy=(0, 0), width=2, height=1, angle=30) assert_almost_equal( - Ellipse(xy=(0, 0), width=1, height=1, angle=0).get_vertices(), - [(-0.5, 0.0), (0.5, 0.0)], - ) - assert_almost_equal( - Ellipse(xy=(0, 0), width=1, height=1, angle=0).get_co_vertices(), - [(0.0, 0.5), (0.0, -0.5)], - ) - - assert_almost_equal( - Ellipse(xy=(0, 0), width=1, height=0.5, angle=90).get_vertices(), - [(0.0, -0.5), (0.0, 0.5)], + ellipse.get_vertices(), + [ + ( + ellipse.center[0] - ellipse.width / 4 * np.sqrt(3), + ellipse.center[1] - ellipse.width / 4, + ), + ( + ellipse.center[0] + ellipse.width / 4 * np.sqrt(3), + ellipse.center[1] + ellipse.width / 4, + ), + ], ) assert_almost_equal( - Ellipse(xy=(0, 0), width=1, height=0.5, angle=90).get_co_vertices(), - [(-0.25, 0.0), (0.25, 0.0)], + ellipse.get_co_vertices(), + [ + ( + ellipse.center[0] - ellipse.height / 4, + ellipse.center[1] + ellipse.height / 4 * np.sqrt(3), + ), + ( + ellipse.center[0] + ellipse.height / 4, + ellipse.center[1] - ellipse.height / 4 * np.sqrt(3), + ), + ], ) + v1, v2 = np.array(ellipse.get_vertices()) + np.testing.assert_almost_equal((v1 + v2) / 2, ellipse.center) + v1, v2 = np.array(ellipse.get_co_vertices()) + np.testing.assert_almost_equal((v1 + v2) / 2, ellipse.center) + + ellipse = Ellipse(xy=(2.252, -10.859), width=2.265, height=1.98, angle=68.78) + v1, v2 = np.array(ellipse.get_vertices()) + np.testing.assert_almost_equal((v1 + v2) / 2, ellipse.center) + v1, v2 = np.array(ellipse.get_co_vertices()) + np.testing.assert_almost_equal((v1 + v2) / 2, ellipse.center) def test_rotate_rect(): From 3a4ee04188d684428313ebbe255f4a277646d42e Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Tue, 2 May 2023 21:19:02 +0200 Subject: [PATCH 25/33] adapted stubs file --- lib/matplotlib/patches.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/patches.pyi b/lib/matplotlib/patches.pyi index 6efb9e3347fc..e9302563083c 100644 --- a/lib/matplotlib/patches.pyi +++ b/lib/matplotlib/patches.pyi @@ -259,8 +259,8 @@ class Ellipse(Patch): def get_corners(self) -> np.ndarray: ... - def get_vertices(self) -> tuple[float, float]: ... - def get_co_vertices(self) -> tuple[float, float]: ... + def get_vertices(self) -> list[tuple[float, float]]: ... + def get_co_vertices(self) -> list[tuple[float, float]]: ... class Annulus(Patch): From 46898de656ef0ef828b060b3fa79bc73770262ba Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Tue, 2 May 2023 21:43:15 +0200 Subject: [PATCH 26/33] resolve pre-commit codespell --- lib/matplotlib/tests/test_patches.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/tests/test_patches.py b/lib/matplotlib/tests/test_patches.py index ac26b75231f7..416242de4d39 100644 --- a/lib/matplotlib/tests/test_patches.py +++ b/lib/matplotlib/tests/test_patches.py @@ -105,7 +105,7 @@ def test_corner_center(): def test_ellipse_vertices(): - # expect 0 for 0 ellipse widht, height + # expect 0 for 0 ellipse width, height ellipse = Ellipse(xy=(0, 0), width=0, height=0, angle=0) assert_almost_equal( ellipse.get_vertices(), From 28437f1e231fd57566953947fe3613ab40b41664 Mon Sep 17 00:00:00 2001 From: Photoniker <17592823+photoniker@users.noreply.github.com> Date: Mon, 8 May 2023 16:00:07 +0200 Subject: [PATCH 27/33] Update galleries/examples/shapes_and_collections/ellipse_arrow.py Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com> --- .../shapes_and_collections/ellipse_arrow.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index 09f527fcfa55..1f0739d6f872 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -18,16 +18,11 @@ # Create a figure and axis fig, ax = plt.subplots(subplot_kw={"aspect": "equal"}) -# Define an ellipse clockwise -center = (2, 4) -width = 30 -height = 20 -angle = 35 ellipse = Ellipse( - xy=center, - width=width, - height=height, - angle=angle, + xy=(2, 4), + width=30, + height=20, + angle=35, facecolor="none", edgecolor="b" ) From 3bbe33f65de433fa97c5926ebfc1f8b17a1159cd Mon Sep 17 00:00:00 2001 From: Photoniker <17592823+photoniker@users.noreply.github.com> Date: Mon, 8 May 2023 20:37:00 +0200 Subject: [PATCH 28/33] Some correction :lipstick: ellipse_arrow.py --- galleries/examples/shapes_and_collections/ellipse_arrow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/galleries/examples/shapes_and_collections/ellipse_arrow.py b/galleries/examples/shapes_and_collections/ellipse_arrow.py index 1f0739d6f872..4bcdc016faa6 100644 --- a/galleries/examples/shapes_and_collections/ellipse_arrow.py +++ b/galleries/examples/shapes_and_collections/ellipse_arrow.py @@ -28,7 +28,7 @@ ) ax.add_patch(ellipse) -# Plot a arrow marker at the end point of minor axis +# Plot an arrow marker at the end point of minor axis vertices = ellipse.get_co_vertices() t = Affine2D().rotate_deg(ellipse.angle) ax.plot( From 9cbe4ef82a994454ca48d5b4ee3df51e0f7c0f40 Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Wed, 10 May 2023 08:06:10 +0200 Subject: [PATCH 29/33] added get_vertices_co_vertices.rst to next_whats_new folder --- doc/users/next_whats_new/get_vertices_co_vertices.rst | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 doc/users/next_whats_new/get_vertices_co_vertices.rst diff --git a/doc/users/next_whats_new/get_vertices_co_vertices.rst b/doc/users/next_whats_new/get_vertices_co_vertices.rst new file mode 100644 index 000000000000..98254a82ce63 --- /dev/null +++ b/doc/users/next_whats_new/get_vertices_co_vertices.rst @@ -0,0 +1,7 @@ +``Ellipse.get_vertices()``, ``Ellipse.get_co_vertices()`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +These methods return the coordinates of ellipse vertices of +major and minor axis. Additionally, an example gallery demo is added which +shows how to add an arrow to an ellipse showing a clockwise or counter-clockwise +rotation of the ellipse. To place the arrow exactly on the ellipse, +the coordinates of the vertices are used. From 49d89d148f18fba10e5258aa0998827e39140538 Mon Sep 17 00:00:00 2001 From: photoniker Date: Sat, 13 May 2023 10:17:24 +0200 Subject: [PATCH 30/33] Update patches.py by .. versionadded:: 3.8 --- lib/matplotlib/patches.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index faf070aadcf1..76be484d3d66 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -1659,6 +1659,8 @@ def get_vertices(self): Return the left and right vertex coordinates of the ellipse. The definition can be found `here `_ + + .. versionadded:: 3.8 """ x0 = self._center[0] - self._width / 2 * np.cos(np.deg2rad(self._angle)) y0 = self._center[1] - self._width / 2 * np.sin(np.deg2rad(self._angle)) @@ -1671,6 +1673,8 @@ def get_co_vertices(self): Return the left and right co-vertex coordinates of the ellipse. The definition can be found `here `_ + + .. versionadded:: 3.8 """ x0 = self._center[0] - self._height / 2 * np.sin(np.deg2rad(self._angle)) y0 = self._center[1] + self._height / 2 * np.cos(np.deg2rad(self._angle)) From 501436fc575193b1e380edce35215daabf1292ee Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Sat, 13 May 2023 22:21:38 +0200 Subject: [PATCH 31/33] get_vertices and get_co_vertices returns now the coordinates of the major and minor axis depending on the length between the coordinates of points --- lib/matplotlib/patches.py | 50 +++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index 76be484d3d66..2dcaa488e65e 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -1654,33 +1654,59 @@ def get_corners(self): return self.get_patch_transform().transform( [(-1, -1), (1, -1), (1, 1), (-1, 1)]) + def _calculate_length_between_points(self, x0, y0, x1, y1): + return np.sqrt((x1 - x0)**2 + (y1 - y0)**2) + + def _calculate_vertices_coordinates(self, return_major: bool = True): + # calculate the vertices of width axis + w_x0 = self._center[0] - self._width / 2 * np.cos(np.deg2rad(self._angle)) + w_y0 = self._center[1] - self._width / 2 * np.sin(np.deg2rad(self._angle)) + w_x1 = self._center[0] + self._width / 2 * np.cos(np.deg2rad(self._angle)) + w_y1 = self._center[1] + self._width / 2 * np.sin(np.deg2rad(self._angle)) + + # calculate the vertices of height axis + h_x0 = self._center[0] - self._height / 2 * np.sin(np.deg2rad(self._angle)) + h_y0 = self._center[1] + self._height / 2 * np.cos(np.deg2rad(self._angle)) + h_x1 = self._center[0] + self._height / 2 * np.sin(np.deg2rad(self._angle)) + h_y1 = self._center[1] - self._height / 2 * np.cos(np.deg2rad(self._angle)) + + if self._calculate_length_between_points( + w_x0, w_y0, w_x1, w_y1 + ) >= self._calculate_length_between_points( + h_x0, h_y0, h_x1, h_y1 + ): # width is major + major = [(w_x0, w_y0), (w_x1, w_y1)] + minor = [(h_x0, h_y0), (h_x1, h_y1)] + else: # minor + major = [(h_x0, h_y0), (h_x1, h_y1)] + minor = [(w_x0, w_y0), (w_x1, w_y1)] + + if return_major: + coordinates = major + else: + coordinates = minor + + return coordinates + def get_vertices(self): """ - Return the left and right vertex coordinates of the ellipse. + Return the vertices coordinates of the ellipse. The definition can be found `here `_ .. versionadded:: 3.8 """ - x0 = self._center[0] - self._width / 2 * np.cos(np.deg2rad(self._angle)) - y0 = self._center[1] - self._width / 2 * np.sin(np.deg2rad(self._angle)) - x1 = self._center[0] + self._width / 2 * np.cos(np.deg2rad(self._angle)) - y1 = self._center[1] + self._width / 2 * np.sin(np.deg2rad(self._angle)) - return [(x0, y0), (x1, y1)] + return self._calculate_vertices_coordinates() def get_co_vertices(self): """ - Return the left and right co-vertex coordinates of the ellipse. + Return the co-vertices coordinates of the ellipse. The definition can be found `here `_ .. versionadded:: 3.8 """ - x0 = self._center[0] - self._height / 2 * np.sin(np.deg2rad(self._angle)) - y0 = self._center[1] + self._height / 2 * np.cos(np.deg2rad(self._angle)) - x1 = self._center[0] + self._height / 2 * np.sin(np.deg2rad(self._angle)) - y1 = self._center[1] - self._height / 2 * np.cos(np.deg2rad(self._angle)) - return [(x0, y0), (x1, y1)] + return self._calculate_vertices_coordinates(return_major=False) class Annulus(Patch): From cf6e95ac01969e68b1b33e57a08d81d40cd7e1b4 Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Tue, 16 May 2023 09:04:38 +0200 Subject: [PATCH 32/33] Changed get_vertices and get_co_vertices using get_patch_transform().transform() for coordinate calculations. --- lib/matplotlib/patches.py | 43 +++++++++------------------------------ 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index 2dcaa488e65e..ecf03ca4051b 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -1657,37 +1657,6 @@ def get_corners(self): def _calculate_length_between_points(self, x0, y0, x1, y1): return np.sqrt((x1 - x0)**2 + (y1 - y0)**2) - def _calculate_vertices_coordinates(self, return_major: bool = True): - # calculate the vertices of width axis - w_x0 = self._center[0] - self._width / 2 * np.cos(np.deg2rad(self._angle)) - w_y0 = self._center[1] - self._width / 2 * np.sin(np.deg2rad(self._angle)) - w_x1 = self._center[0] + self._width / 2 * np.cos(np.deg2rad(self._angle)) - w_y1 = self._center[1] + self._width / 2 * np.sin(np.deg2rad(self._angle)) - - # calculate the vertices of height axis - h_x0 = self._center[0] - self._height / 2 * np.sin(np.deg2rad(self._angle)) - h_y0 = self._center[1] + self._height / 2 * np.cos(np.deg2rad(self._angle)) - h_x1 = self._center[0] + self._height / 2 * np.sin(np.deg2rad(self._angle)) - h_y1 = self._center[1] - self._height / 2 * np.cos(np.deg2rad(self._angle)) - - if self._calculate_length_between_points( - w_x0, w_y0, w_x1, w_y1 - ) >= self._calculate_length_between_points( - h_x0, h_y0, h_x1, h_y1 - ): # width is major - major = [(w_x0, w_y0), (w_x1, w_y1)] - minor = [(h_x0, h_y0), (h_x1, h_y1)] - else: # minor - major = [(h_x0, h_y0), (h_x1, h_y1)] - minor = [(w_x0, w_y0), (w_x1, w_y1)] - - if return_major: - coordinates = major - else: - coordinates = minor - - return coordinates - def get_vertices(self): """ Return the vertices coordinates of the ellipse. @@ -1696,7 +1665,11 @@ def get_vertices(self): .. versionadded:: 3.8 """ - return self._calculate_vertices_coordinates() + if self.width < self.height: + ret = self.get_patch_transform().transform([(0, 1), (0, -1)]) + else: + ret = self.get_patch_transform().transform([(1, 0), (-1, 0)]) + return [tuple(x) for x in ret] def get_co_vertices(self): """ @@ -1706,7 +1679,11 @@ def get_co_vertices(self): .. versionadded:: 3.8 """ - return self._calculate_vertices_coordinates(return_major=False) + if self.width < self.height: + ret = self.get_patch_transform().transform([(1, 0), (-1, 0)]) + else: + ret = self.get_patch_transform().transform([(0, 1), (0, -1)]) + return [tuple(x) for x in ret] class Annulus(Patch): From 896a7754d16bfe4b419297d73732823fdc50e774 Mon Sep 17 00:00:00 2001 From: Johann Krauter Date: Tue, 16 May 2023 12:53:57 +0200 Subject: [PATCH 33/33] fix in unittest due to different ordering of vertices return values --- lib/matplotlib/tests/test_patches.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/tests/test_patches.py b/lib/matplotlib/tests/test_patches.py index 416242de4d39..fd872bac98d4 100644 --- a/lib/matplotlib/tests/test_patches.py +++ b/lib/matplotlib/tests/test_patches.py @@ -120,14 +120,14 @@ def test_ellipse_vertices(): assert_almost_equal( ellipse.get_vertices(), [ - ( - ellipse.center[0] - ellipse.width / 4 * np.sqrt(3), - ellipse.center[1] - ellipse.width / 4, - ), ( ellipse.center[0] + ellipse.width / 4 * np.sqrt(3), ellipse.center[1] + ellipse.width / 4, ), + ( + ellipse.center[0] - ellipse.width / 4 * np.sqrt(3), + ellipse.center[1] - ellipse.width / 4, + ), ], ) assert_almost_equal( 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