Skip to content

Commit 09dd9aa

Browse files
committed
Add some helper methods to Patches
1 parent 98115e9 commit 09dd9aa

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

lib/matplotlib/patches.py

+36
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,26 @@ def get_xy(self):
806806
"""Return the left and bottom coords of the rectangle as a tuple."""
807807
return self._x0, self._y0
808808

809+
def get_edge_midpoints(self):
810+
"""
811+
Return midpoints of the edges of the rectangle, moving anti-clockwise
812+
from the center of the left-hand edge.
813+
"""
814+
return self.get_patch_transform().transform(
815+
[(0, 0.5), (0.5, 1), (1, 0.5), (0.5, 0)])
816+
817+
def get_corners(self):
818+
"""
819+
Return the corners of the rectangle, moving anti-clockwise from
820+
(x0, y0).
821+
"""
822+
return self.get_patch_transform().transform(
823+
[(0, 0), (0, 1), (1, 1), (1, 0)])
824+
825+
def get_center(self):
826+
"""Return the centre of the rectangle."""
827+
return self.get_patch_transform().transform((0.5, 0.5))
828+
809829
def get_width(self):
810830
"""Return the width of the rectangle."""
811831
return self._width
@@ -1657,6 +1677,22 @@ def get_angle(self):
16571677

16581678
angle = property(get_angle, set_angle)
16591679

1680+
def get_corners(self):
1681+
"""
1682+
Return the corners of the ellipse bounding box, moving anti-clockwise
1683+
from the lower left.
1684+
"""
1685+
return self.get_patch_transform().transform(
1686+
[(-1, -1), (-1, 1), (1, 1), (1, -1)])
1687+
1688+
def get_edge_midpoints(self):
1689+
"""
1690+
Return the edge midpoints of the ellipse bounding box, moving
1691+
anti-clockwise from the left hand edge.
1692+
"""
1693+
return self.get_patch_transform().transform(
1694+
[(-1, 0), (0, 1), (1, 0), (0, -1)])
1695+
16601696

16611697
class Annulus(Patch):
16621698
"""

lib/matplotlib/tests/test_patches.py

+49-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import pytest
77

88
import matplotlib as mpl
9-
from matplotlib.patches import (Annulus, Patch, Polygon, Rectangle,
9+
from matplotlib.patches import (Annulus, Ellipse, Patch, Polygon, Rectangle,
1010
FancyArrowPatch)
1111
from matplotlib.testing.decorators import image_comparison, check_figures_equal
1212
from matplotlib.transforms import Bbox
@@ -54,6 +54,54 @@ def test_Polygon_close():
5454
assert_array_equal(p.get_xy(), xyclosed)
5555

5656

57+
def test_corner_center():
58+
loc = [10, 20]
59+
width = 1
60+
height = 2
61+
62+
# Rectangle
63+
# No rotation
64+
corners = ((10, 20), (10, 22), (11, 22), (11, 20))
65+
rect = Rectangle(loc, width, height)
66+
assert_array_equal(rect.get_corners(), corners)
67+
assert_array_equal(rect.get_center(), (10.5, 21))
68+
69+
# 90 deg rotation
70+
corners_rot = ((10, 20), (8, 20), (8, 21), (10, 21))
71+
rect.set_angle(90)
72+
assert_array_equal(rect.get_corners(), corners_rot)
73+
assert_array_equal(rect.get_center(), (9, 20.5))
74+
75+
# Rotation not a multiple of 90 deg
76+
theta = 33
77+
t = mtransforms.Affine2D().rotate_around(*loc, np.deg2rad(theta))
78+
corners_rot = t.transform(corners)
79+
rect.set_angle(theta)
80+
assert_almost_equal(rect.get_corners(), corners_rot)
81+
82+
# Ellipse
83+
loc = [loc[0] + width / 2,
84+
loc[1] + height / 2]
85+
ellipse = Ellipse(loc, width, height)
86+
87+
# No rotation
88+
assert_array_equal(ellipse.get_corners(), corners)
89+
90+
# 90 deg rotation
91+
corners_rot = ((11.5, 20.5), (9.5, 20.5), (9.5, 21.5), (11.5, 21.5))
92+
ellipse.set_angle(90)
93+
assert_array_equal(ellipse.get_corners(), corners_rot)
94+
# Rotation shouldn't change ellipse center
95+
assert_array_equal(ellipse.get_center(), loc)
96+
97+
# Rotation not a multiple of 90 deg
98+
theta = 33
99+
t = mtransforms.Affine2D().rotate_around(*loc, np.deg2rad(theta))
100+
corners_rot = t.transform(corners)
101+
ellipse.set_angle(theta)
102+
assert_almost_equal(ellipse.get_corners(), corners_rot)
103+
104+
57105
def test_rotate_rect():
58106
loc = np.asarray([1.0, 2.0])
59107
width = 2

0 commit comments

Comments
 (0)