Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fdeed45

Browse files
committed
Allow Rectangle and Ellipse selectors to be rotated
1 parent 4085fc7 commit fdeed45

File tree

4 files changed

+185
-67
lines changed

4 files changed

+185
-67
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Rotating selectors
2+
------------------
3+
4+
The `~matplotlib.widgets.RectangleSelector` and
5+
`~matplotlib.widgets.EllipseSelector` can now be rotated by pressing the 'r' key,
6+
and dragging one of their control points. The rotation is done about the first
7+
vertex placed when drawing the selector.

lib/matplotlib/patches.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -779,10 +779,22 @@ def get_patch_transform(self):
779779
# important to call the accessor method and not directly access the
780780
# transformation member variable.
781781
bbox = self.get_bbox()
782-
return (transforms.BboxTransformTo(bbox)
783-
+ transforms.Affine2D().rotate_deg_around(
782+
return (transforms.BboxTransformTo(bbox) +
783+
transforms.Affine2D().rotate_deg_around(
784784
bbox.x0, bbox.y0, self.angle))
785785

786+
def _get_translate_rotate_transform(self):
787+
"""
788+
Return a transform that translates the LH corner to the origin,
789+
and de-rotates the rectangle.
790+
"""
791+
rotate = transforms.Affine2D().rotate_deg_around(self.get_x(),
792+
self.get_y(),
793+
-self.angle)
794+
translate = transforms.Affine2D().translate(-self.get_x(),
795+
-self.get_y())
796+
return rotate + translate
797+
786798
def get_x(self):
787799
"""Return the left coordinate of the rectangle."""
788800
return self._x0

lib/matplotlib/tests/test_widgets.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,32 @@ def onselect(epress, erelease):
143143
tool._corner_handles.artist.get_markeredgecolor(), 'b')
144144

145145

146+
def test_rectangle_rotate():
147+
ax = get_ax()
148+
149+
def onselect(epress, erelease):
150+
pass
151+
152+
tool = widgets.RectangleSelector(ax, onselect=onselect, interactive=True,
153+
state_modifier_keys={'rotate': 'r'})
154+
# Draw rectangle
155+
do_event(tool, 'press', xdata=100, ydata=100)
156+
do_event(tool, 'onmove', xdata=130, ydata=140)
157+
do_event(tool, 'release', xdata=130, ydata=140)
158+
assert tool.extents == (100, 130, 100, 140)
159+
160+
# Rotate by 45 degrees anticlockwise
161+
do_event(tool, 'press', xdata=130, ydata=140, key='r')
162+
do_event(tool, 'onmove', xdata=100, ydata=150, key='r')
163+
do_event(tool, 'release', xdata=100, ydata=200, key='r')
164+
# Extents shouldn't change (as shape of rectangle hasn't changed)
165+
assert tool.extents == (100, 130, 100, 140)
166+
# Corners should move
167+
# The third corner is at (100, 150), as the diagonal of the rectangle has
168+
# length 50
169+
assert tool.corners == ((100, 124, 100, 76), (100, 118, 150, 132))
170+
171+
146172
def check_span(*args, **kwargs):
147173
ax = get_ax()
148174

0 commit comments

Comments
 (0)