8000 Merge pull request #20928 from meeseeksmachine/auto-backport-of-pr-20… · matplotlib/matplotlib@3bbdbdf · GitHub
[go: up one dir, main page]

Skip to content

Commit 3bbdbdf

Browse files
authored
Merge pull request #20928 from meeseeksmachine/auto-backport-of-pr-20889-on-v3.5.x
Backport PR #20889 on branch v3.5.x (Fix clearing selector)
2 parents 71c526e + 5fa8b29 commit 3bbdbdf

File tree

3 files changed

+93
-4
lines changed

3 files changed

+93
-4
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Clear selector
2+
--------------
3+
The selectors (`~matplotlib.widgets.SpanSelector`, `~matplotlib.widgets.RectangleSelector`,
4+
`~matplotlib.widgets.EllipseSelector`, `~matplotlib.widgets.PolygonSelector` and
5+
`~matplotlib.widgets.LassoSelector` have a new method *clear*, which will clear
6+
the current selection and get the selector ready to make a new selection. This
7+
is equivalent to press the *escape* key.

lib/matplotlib/tests/test_widgets.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,82 @@ def onselect(epress, erelease):
460460
assert artist.get_alpha() == 0.3
461461

462462

463+
@pytest.mark.parametrize('selector', ['span', 'rectangle'])
464+
def test_selector_clear(selector):
465+
ax = get_ax()
466+
467+
def onselect(*args):
468+
pass
469+
470+
kwargs = dict(ax=ax, onselect=onselect, interactive=True)
471+
if selector == 'span':
472+
Selector = widgets.SpanSelector
473+
kwargs['direction'] = 'horizontal'
474+
else:
475+
Selector = widgets.RectangleSelector
476+
477+
tool = Selector(**kwargs)
478+
do_event(tool, 'press', xdata=10, ydata=10, button=1)
479+
do_event(tool, 'onmove', xdata=100, ydata=120, button=1)
480+
do_event(tool, 'release', xdata=100, ydata=120, button=1)
481+
482+
# press-release event outside the selector to clear the selector
483+
do_event(tool, 'press', xdata=130, ydata=130, button=1)
484+
do_event(tool, 'release', xdata=130, ydata=130, button=1)
485+
assert not tool._selection_completed
486+
487+
ax = get_ax()
488+
kwargs['ignore_event_outside'] = True
489+
tool = Selector(**kwargs)
490+
assert tool.ignore_event_outside
491+
do_event(tool, 'press', xdata=10, ydata=10, button=1)
492+
do_event(tool, 'onmove', xdata=100, ydata=120, button=1)
493+
do_event(tool, 'release', xdata=100, ydata=120, button=1)
494+
495+
# press-release event outside the selector ignored
496+
do_event(tool, 'press', xdata=130, ydata=130, button=1)
497+
do_event(tool, 'release', xdata=130, y 10000 data=130, button=1)
498+
assert tool._selection_completed
499+
500+
do_event(tool, 'on_key_press', key='escape')
501+
assert not tool._selection_completed
502+
503+
504+
@pytest.mark.parametrize('selector', ['span', 'rectangle'])
505+
def test_selector_clear_method(selector):
506+
ax = get_ax()
507+
508+
def onselect(*args):
509+
pass
510+
511+
if selector == 'span':
512+
tool = widgets.SpanSelector(ax, onselect, 'horizontal',
513+
interactive=True,
514+
ignore_event_outside=True)
515+
else:
516+
tool = widgets.RectangleSelector(ax, onselect, interactive=True)
517+
do_event(tool, 'press', xdata=10, ydata=10, button=1)
518+
do_event(tool, 'onmove', xdata=100, ydata=120, button=1)
519+
do_event(tool, 'release', xdata=100, ydata=120, button=1)
520+
assert tool._selection_completed
521+
assert tool.visible
522+
if selector == 'span':
523+
assert tool.extents == (10, 100)
524+
525+
tool.clear()
526+
assert not tool._selection_completed
527+
assert not tool.visible
528+
529+
# Do another cycle of events to make sure we can
530+
do_event(tool, 'press', xdata=10, ydata=10, button=1)
531+
do_event(tool, 'onmove', xdata=50, ydata=120, button=1)
532+
do_event(tool, 'release', xdata=50, ydata=120, button=1)
533+
assert tool._selection_completed
534+
assert tool.visible
535+
if selector == 'span':
536+
assert tool.extents == (10, 50)
537+
538+
463539
def test_tool_line_handle():
464540
ax = get_ax()
465541

lib/matplotlib/widgets.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,9 +1978,7 @@ def on_key_press(self, event):
19781978
key = event.key or ''
19791979
key = key.replace('ctrl', 'control')
19801980
if key == self.state_modifier_keys['clear']:
1981-
for artist in self.artists:
1982-
artist.set_visible(False)
1983-
self.update()
1981+
self.clear()
19841982
return
19851983
for (state, modifier) in self.state_modifier_keys.items():
19861984
if modifier in key:
@@ -2008,6 +2006,12 @@ def set_visible(self, visible):
20082006
for artist in self.artists:
20092007
artist.set_visible(visible)
20102008

2009+
def clear(self):
2010+
"""Clear the selection and set the selector ready to make a new one."""
2011+
self._selection_completed = False
2012+
self.set_visible(False)
2013+
self.update()
2014+
20112015
@property
20122016
def artists(self):
20132017
"""Tuple of the artists of the selector."""
@@ -2354,9 +2358,11 @@ def _hover(self, event):
23542358
if self.ignore(event):
23552359
return
23562360

2357-
if self._active_handle is not None:
2361+
if self._active_handle is not None or not self._selection_completed:
23582362
# Do nothing if button is pressed and a handle is active, which may
23592363
# occur with drag_from_anywhere=True.
2364+
# Do nothing if selection is not completed, which occurs when
2365+
# a selector has been cleared
23602366
return
23612367

23622368
_, e_dist = self._edge_handles.closest(event.x, event.y)

0 commit comments

Comments
 (0)
0