8000 Replace the `data_coordinates` state by the `use_data_coordinates` ar… · matplotlib/matplotlib@cdfd423 · GitHub
[go: up one dir, main page]

Skip to content

Commit cdfd423

Browse files
committed
Replace the data_coordinates state by the use_data_coordinates argument
1 parent efce8b1 commit cdfd423

File tree

3 files changed

+51
-53
lines changed

3 files changed

+51
-53
lines changed

doc/users/next_whats_new/selector_improvement.rst

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ The rotation is enabled or disable by striking the *r* key
88
*selector.add_state('rotate')*.
99

1010
The aspect ratio of the axes can now be taken into account when using the
11-
"square" state. This can be enable or disable by striking the *d* key
12-
(default value of 'data_coordinates' in *state_modifier_keys*)
13-
or by calling *selector.add_state('rotate')*.
11+
"square" state. This is enable by specifying *use_data_coordinates='True'* when
12+
the selector is initialized.
1413

1514
In addition to changing selector state interactively using the modifier keys
1615
defined in *state_modifier_keys*, the selector state can now be changed
@@ -29,12 +28,12 @@ programmatically using the *add_state* and *remove_state* method.
2928
ax = fig.add_subplot()
3029
ax.plot(values, values)
3130
32-
selector = RectangleSelector(ax, print, interactive=True, drag_from_anywhere=True)
31+
selector = RectangleSelector(ax, print, interactive=True,
32+
drag_from_anywhere=True,
33+
use_data_coordinates=True)
3334
selector.add_state('rotate') # alternatively press 'r' key
3435
# rotate the selector interactively
3536
3637
selector.remove_state('rotate') # alternatively press 'r' key
3738
3839
selector.add_state('square')
39-
# to keep the aspect ratio in data coordinates
40-
selector.add_state('data_coordinates')

lib/matplotlib/tests/test_widgets.py

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,6 @@ def onselect(epress, erelease):
190190
tool.add_state('move')
191191
tool.add_state('square')
192192
tool.add_state('center')
193-
tool.add_state('data_coordinates')
194193

195194

196195
@pytest.mark.parametrize('add_state', [True, False])
@@ -466,48 +465,49 @@ def onselect(epress, erelease):
466465
do_event(tool, 'release', xdata=130, ydata=140)
467466
assert tool.extents == (100, 130, 100, 140)
468467
assert len(tool._state) == 0
469-
for state in ['rotate', 'data_coordinates', 'square', 'center']:
468+
for state in ['rotate', 'square', 'center']:
470469
tool.add_state(state)
471470
assert len(tool._state) == 1
472471
tool.remove_state(state)
473472
assert len(tool._state) == 0
474473

475474

476-
def test_rectangle_resize_square_center_aspect():
475+
@pytest.mark.parametrize('use_data_coordinates', [False, True])
476+
def test_rectangle_resize_square_center_aspect(use_data_coordinates):
477477
ax = get_ax()
478478
ax.set_aspect(0.8)
479479

480480
def onselect(epress, erelease):
481481
pass
482482

483-
tool = widgets.RectangleSelector(ax, onselect, interactive=True)
483+
tool = widgets.RectangleSelector(ax, onselect, interactive=True,
484+
use_data_coordinates=use_data_coordinates)
484485
# Create rectangle
485486
_resize_rectangle(tool, 70, 65, 120, 115)
487+
assert tool.extents == (70.0, 120.0, 65.0, 115.0)
486488
tool.add_state('square')
487489
tool.add_state('center')
488-
assert tool.extents == (70.0, 120.0, 65.0, 115.0)
489-
490-
# resize E handle
491-
extents = tool.extents
492-
xdata, ydata = extents[1], extents[3]
493-
xdiff = 10
494-
xdata_new, ydata_new = xdata + xdiff, ydata
495-
ychange = xdiff * 1 / tool._aspect_ratio_correction
496-
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new)
497-
assert_allclose(tool.extents, [extents[0] - xdiff, xdata_new,
498-
46.25, 133.75])
499490

500-
# use data coordinates
501-
do_event(tool, 'on_key_press', key='d')
502-
# resize E handle
503-
extents = tool.extents
504-
xdata, ydata, width = extents[1], extents[3], extents[1] - extents[0]
505-
xdiff, ycenter = 10, extents[2] + (extents[3] - extents[2]) / 2
506-
xdata_new, ydata_new = xdata + xdiff, ydata
507-
ychange = width / 2 + xdiff
508-
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new)
509-
assert_allclose(tool.extents, [extents[0] - xdiff, xdata_new,
510-
ycenter - ychange, ycenter + ychange])
491+
if use_data_coordinates:
492+
# resize E handle
493+
extents = tool.extents
494+
xdata, ydata, width = extents[1], extents[3], extents[1] - extents[0]
495+
xdiff, ycenter = 10, extents[2] + (extents[3] - extents[2]) / 2
496+
xdata_new, ydata_new = xdata + xdiff, ydata
497+
ychange = width / 2 + xdiff
498+
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new)
499+
assert_allclose(tool.extents, [extents[0] - xdiff, xdata_new,
500+
ycenter - ychange, ycenter + ychange])
501+
else:
502+
# resize E handle
503+
extents = tool.extents
504+
xdata, ydata = extents[1], extents[3]
505+
xdiff = 10
506+
xdata_new, ydata_new = xdata + xdiff, ydata
507+
ychange = xdiff * 1 / tool._aspect_ratio_correction
508+
_resize_rectangle(tool, xdata, ydata, xdata_new, ydata_new)
509+
assert_allclose(tool.extents, [extents[0] - xdiff, xdata_new,
510+
46.25, 133.75])
511511

512512

513513
def test_ellipse():

lib/matplotlib/widgets.py

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,7 +1801,7 @@ def _update(self):
18011801
class _SelectorWidget(AxesWidget):
18021802

18031803
def __init__(self, ax, onselect, useblit=False, button=None,
1804-
state_modifier_keys=None):
1804+
state_modifier_keys=None, use_data_coordinates=False):
18051805
super().__init__(ax)
18061806

18071807
self.visible = True
@@ -1811,9 +1811,9 @@ def __init__(self, ax, onselect, useblit=False, button=None,
18111811

18121812
self._state_modifier_keys = dict(move=' ', clear='escape',
18131813
square='shift', center='control',
1814-
data_coordinates='d',
18151814
rotate='r')
18161815
self._state_modifier_keys.update(state_modifier_keys or {})
1816+
self._use_data_coordinates = use_data_coordinates
18171817

18181818
self.background = None
18191819

@@ -1999,17 +1999,15 @@ def on_key_press(self, event):
19991999
return
20002000
for (state, modifier) in self._state_modifier_keys.items():
20012001
if modifier in key.split('+'):
2002-
# 'rotate' and 'data_coordinates' are changing _state on
2003-
# press and are not removed from _state when releasing
2004-
if state in ['rotate', 'data_coordinates']:
2002+
# 'rotate' is changing _state on press and is not removed
2003+
# from _state when releasing
2004+
if state == 'rotate':
20052005
if state in self._state:
20062006
self._state.discard(state)
20072007
else:
20082008
self._state.add(state)
20092009
else:
20102010
self._state.add(state)
2011-
if 'data_coordinates' in state:
2012-
self._set_aspect_ratio_correction()
20132011
self._on_key_press(event)
20142012

20152013
def _on_key_press(self, event):
@@ -2021,10 +2019,9 @@ def on_key_release(self, event):
20212019
key = event.key or ''
20222020
key = key.replace('ctrl', 'control')
20232021
for (state, modifier) in self._state_modifier_keys.items():
2024-
# 'rotate' and 'data_coordinates' are changing _state on
2025-
# press and are not removed from _state when releasing
2026-
if (modifier in key.split('+') and
2027-
state not in ['rotate', 'data_coordinates']):
2022+
# 'rotate' is changing _state on press and is not removed
2023+
# from _state when releasing
2024+
if modifier in key.split('+') and state != 'rotate':
20282025
self._state.discard(state)
20292026
self._on_key_release(event)
20302027

@@ -2236,7 +2233,6 @@ def __init__(self, ax, onselect, direction, minspan=0, useblit=False,
22362233
state_modifier_keys = dict(clear='escape',
22372234
square='not-applicable',
22382235
center='not-applicable',
2239-
data_coordinates='not-applicable',
22402236
rotate='not-applicable')
22412237
super().__init__(ax, onselect, useblit=useblit, button=button,
22422238
state_modifier_keys=state_modifier_keys)
@@ -2811,13 +2807,11 @@ def onselect(eclick: MouseEvent, erelease: MouseEvent)
28112807
- "clear": Clear the current shape, default: "escape".
28122808
- "square": Make the shape square, default: "shift".
28132809
- "center": change the shape around its center, default: "ctrl".
2814-
- "data_coordinates": define if data or figure coordinates should be
2815-
used to define the square shape, default: "d"
28162810
- "rotate": Rotate the shape around its center, default: "r".
28172811
28182812
"square" and "center" can be combined. The square shape can be defined
2819-
in data or figure coordinates as determined by the ``data_coordinates``
2820-
modifier, which can be enable and disable by pressing the 'd' key.
2813+
in data or figure coordinates as determined by the
2814+
``use_data_coordinates`` argument specified when creating the selector.
28212815
28222816
drag_from_anywhere : bool, default: False
28232817
If `True`, the widget can be moved by clicking anywhere within
@@ -2827,6 +2821,10 @@ def onselect(eclick: MouseEvent, erelease: MouseEvent)
28272821
If `True`, the event triggered outside the span selector will be
28282822
ignored.
28292823
2824+
use_data_coordinates : bool, default: False
2825+
If `True`, the "square" shape of the selector is defined in
2826+
data coordinates instead of figure coordinates.
2827+
28302828
"""
28312829

28322830

@@ -2871,9 +2869,11 @@ def __init__(self, ax, onselect, drawtype='box',
28712869
lineprops=None, props=None, spancoords='data',
28722870
button=None, grab_range=10, handle_props=None,
28732871
interactive=False, state_modifier_keys=None,
2874-
drag_from_anywhere=False, ignore_event_outside=False):
2872+
drag_from_anywhere=False, ignore_event_outside=False,
2873+
use_data_coordinates=False):
28752874
super().__init__(ax, onselect, useblit=useblit, button=button,
2876-
state_modifier_keys=state_modifier_keys)
2875+
state_modifier_keys=state_modifier_keys,
2876+
use_data_coordinates=use_data_coordinates)
28772877

28782878
self.visible = True
28792879
self._interactive = interactive
@@ -3076,7 +3076,7 @@ def _onmove(self, event):
30763076
# refmax is used when moving the corner handle with the square state
30773077
# and is the maximum between refx and refy
30783078
refmax = None
3079-
if 'data_coordinates' in state:
3079+
if self._use_data_coordinates:
30803080
refx, refy = dx, dy
30813081
else:
30823082
# Add 1e-6 to avoid divided by zero error
@@ -3213,7 +3213,7 @@ def _set_aspect_ratio_correction(self):
32133213
return
32143214

32153215
self._selection_artist._aspect_ratio_correction = aspect_ratio
3216-
if 'data_coordinates' in self._state:
3216+
if self._use_data_coordinates:
32173217
self._aspect_ratio_correction = 1
32183218
else:
32193219
self._aspect_ratio_correction = aspect_ratio
@@ -3581,7 +3581,6 @@ def __init__(self, ax, onselect, useblit=False,
35813581
move_all='shift', move='not-applicable',
35823582
square='not-applicable',
35833583
center='not-applicable',
3584-
data_coordinates='not-applicable',
35853584
rotate='not-applicable')
35863585
super().__init__(ax, onselect, useblit=useblit,
35873586
state_modifier_keys=state_modifier_keys)

0 commit comments

Comments
 (0)
0