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

Skip to content

Commit 4186848

Browse files
committed
Allow Rectangle and Ellipse selectors to be rotated
1 parent 8fda099 commit 4186848

File tree

4 files changed

+187
-68
lines changed

4 files changed

+187
-68
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
@@ -189,6 +189,32 @@ def onselect(epress, erelease):
189189
tool._corner_handles.artist.get_markeredgecolor(), 'b')
190190

191191

192+
def test_rectangle_rotate():
193+
ax = get_ax()
194+
195+
def onselect(epress, erelease):
196+
pass
197+
198+
tool = widgets.RectangleSelector(ax, onselect=onselect, interactive=True,
199+
state_modifier_keys={'rotate': 'r'})
200+
# Draw rectangle
201+
do_event(tool, 'press', xdata=100, ydata=100)
202+
do_event(tool, 'onmove', xdata=130, ydata=140)
203+
do_event(tool, 'release', xdata=130, ydata=140)
204+
assert tool.extents == (100, 130, 100, 140)
205+
206+
# Rotate by 45 degrees anticlockwise
207+
do_event(tool, 'press', xdata=130, ydata=140, key='r')
208+
do_event(tool, 'onmove', xdata=100, ydata=150, key='r')
209+
do_event(tool, 'release', xdata=100, ydata=200, key='r')
210+
# Extents shouldn't change (as shape of rectangle hasn't changed)
211+
assert tool.extents == (100, 130, 100, 140)
212+
# Corners should move
213+
# The third corner is at (100, 150), as the diagonal of the rectangle has
214+
# length 50
215+
assert tool.corners == ((100, 124, 100, 76), (100, 118, 150, 132))
216+
217+
192218
def check_span(*args, **kwargs):
193219
ax = get_ax()
194220

0 commit comments

Comments
 (0)