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

Skip to content

Commit 7645b29

Browse files
committed
Only allow rotations on equal-aspect Axes
1 parent fe4bda0 commit 7645b29

File tree

3 files changed

+47
-9
lines changed

3 files changed

+47
-9
lines changed

doc/users/next_whats_new/selector_rotate.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ Rotating selectors
22
------------------
33

44
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.
5+
`~matplotlib.widgets.EllipseSelector` can now be rotated by pressing the 'r'
6+
key, and dragging one of their control points. This is currently only
7+
implemented for equal-aspect axes. The rotation is done about the
8+
first vertex placed when drawing the selector.

lib/matplotlib/tests/test_widgets.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,38 @@ def onselect(epress, erelease):
226226
assert tool.corners == ((100, 112, 100, 88), (100, 109, 125, 116))
227227

228228

229+
@pytest.mark.parametrize('selector_class', [widgets.RectangleSelector,
230+
widgets.EllipseSelector])
231+
def test_rotate_warning(selector_class):
232+
# Check that a warning is raised when trying to rotate on a
233+
# non-equal aspect Axes.
234+
ax = get_ax()
235+
236+
def onselect(epress, erelease):
237+
pass
238+
239+
tool = selector_class(ax, onselect=onselect, interactive=True)
240+
ax.set_aspect(2)
241+
242+
# Draw rectangle
243+
do_event(tool, 'press', xdata=100, ydata=100)
244+
do_event(tool, 'onmove', xdata=130, ydata=140)
245+
do_event(tool, 'release', xdata=130, ydata=140)
246+
old_corners = tool.corners
247+
248+
# Try to rotate
249+
do_event(tool, 'on_key_press', key='r')
250+
do_event(tool, 'press', xdata=130, ydata=140)
251+
# Check warning is raised
252+
with pytest.warns(UserWarning, match='Rotation is only implemented for '
253+
'equal-aspect Axes.'):
254+
do_event(tool, 'onmove', xdata=100, ydata=150)
255+
do_event(tool, 'release', xdata=100, ydata=200)
256+
do_event(tool, 'on_key_release', key='r')
257+
# Check that corners haven't moved
258+
assert tool.corners == old_corners
259+
260+
229261
def check_span(*args, **kwargs):
230262
ax = get_ax()
231263

lib/matplotlib/widgets.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from contextlib import ExitStack
1313
import copy
1414
from numbers import Integral, Number
15+
import warnings
1516

1617
import numpy as np
1718

@@ -2269,7 +2270,7 @@ def onselect(eclick: MouseEvent, erelease: MouseEvent)
22692270
- "center": Make the initial point the center of the shape,
22702271
default: "ctrl".
22712272
- "rotate": Rotate the shape around its corner,
2272-
default: "r".
2273+
default: "r". This currently only works for equal-aspect axes.
22732274
22742275
"square" and "center" can be combined.
22752276
@@ -2452,11 +2453,15 @@ def _onmove(self, event):
24522453

24532454
# rotate existing shape
24542455
if 'rotate' in self.state:
2455-
rotation_new = np.arctan2(ymove - y0,
2456-
xmove - x0)
2457-
rotation_old = np.arctan2(self._prev_ymove - y0,
2458-
self._prev_xmove - x0)
2459-
rotation += rotation_new - rotation_old
2456+
if self.ax.get_aspect() == 1:
2457+
rotation_new = np.arctan2(ymove - y0,
2458+
xmove - x0)
2459+
rotation_old = np.arctan2(self._prev_ymove - y0,
2460+
self._prev_xmove - x0)
2461+
rotation += rotation_new - rotation_old
2462+
else:
2463+
warnings.warn('Rotation is only implemented for '
2464+
'equal-aspect Axes.')
24602465

24612466
# move existing shape
24622467
elif ('move' in self.state or

0 commit comments

Comments
 (0)