Skip to content

Improve RectangleSelector Rotation revisited and rebased #26833

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
44 changes: 22 additions & 22 deletions lib/matplotlib/patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -799,13 +799,6 @@ def __init__(self, xy, width, height, *,
self._height = height
self.angle = float(angle)
self.rotation_point = rotation_point
# Required for RectangleSelector with axes aspect ratio != 1
# The patch is defined in data coordinates and when changing the
# selector with square modifier and not in data coordinates, we need
# to correct for the aspect ratio difference between the data and
# display coordinate systems. Its value is typically provide by
# Axes._get_aspect_ratio()
self._aspect_ratio_correction = 1.0
self._convert_units() # Validate the inputs.

def get_path(self):
Expand Down Expand Up @@ -833,13 +826,11 @@ def get_patch_transform(self):
rotation_point = bbox.x0, bbox.y0
else:
rotation_point = self.rotation_point
return transforms.BboxTransformTo(bbox) \
+ transforms.Affine2D() \
.translate(-rotation_point[0], -rotation_point[1]) \
.scale(1, self._aspect_ratio_correction) \
.rotate_deg(self.angle) \
.scale(1, 1 / self._aspect_ratio_correction) \
.translate(*rotation_point)
return (transforms.BboxTransformTo(bbox) +
transforms.Affine2D()
.translate(-rotation_point[0], -rotation_point[1])
.rotate_deg(self.angle)
.translate(*rotation_point))

@property
def rotation_point(self):
Expand Down Expand Up @@ -877,6 +868,14 @@ def get_corners(self):
return self.get_patch_transform().transform(
[(0, 0), (1, 0), (1, 1), (0, 1)])

def _get_edge_midpoints(self):
"""
Return the edge midpoints of the rectangle, moving anti-clockwise from
the centre of the left-hand edge.
"""
return self.get_patch_transform().transform(
[(0, 0.5), (0.5, 0), (1, 0.5), (0.5, 1)])

def get_center(self):
"""Return the centre of the rectangle."""
return self.get_patch_transform().transform((0.5, 0.5))
Expand Down Expand Up @@ -1650,12 +1649,6 @@ def __init__(self, xy, width, height, *, angle=0, **kwargs):
self._width, self._height = width, height
self._angle = angle
self._path = Path.unit_circle()
# Required for EllipseSelector with axes aspect ratio != 1
# The patch is defined in data coordinates and when changing the
# selector with square modifier and not in data coordinates, we need
# to correct for the aspect ratio difference between the data and
# display coordinate systems.
self._aspect_ratio_correction = 1.0
# Note: This cannot be calculated until this is added to an Axes
self._patch_transform = transforms.IdentityTransform()

Expand All @@ -1673,9 +1666,8 @@ def _recompute_transform(self):
width = self.convert_xunits(self._width)
height = self.convert_yunits(self._height)
self._patch_transform = transforms.Affine2D() \
.scale(width * 0.5, height * 0.5 * self._aspect_ratio_correction) \
.scale(width * 0.5, height * 0.5) \
.rotate_deg(self.angle) \
.scale(1, 1 / self._aspect_ratio_correction) \
.translate(*center)

def get_path(self):
Expand Down Expand Up @@ -1794,6 +1786,14 @@ def get_co_vertices(self):
ret = self.get_patch_transform().transform([(0, 1), (0, -1)])
return [tuple(x) for x in ret]

def _get_edge_midpoints(self):
"""
Return the edge midpoints of the ellipse, moving anti-clockwise from
the centre of the left-hand edge.
"""
return self.get_patch_transform().transform(
[(-1, 0), (0, -1), (1, 0), (0, 1)])


class Annulus(Patch):
"""
Expand Down
Loading