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

Skip to content

Commit 8150af7

Browse files
committed
Merge pull request #3937 from blink1073/rectangle_selector_upgrade
ENH: Rectangle Selector Upgrade
2 parents 6e281f0 + 819804f commit 8150af7

File tree

3 files changed

+653
-131
lines changed

3 files changed

+653
-131
lines changed

examples/widgets/rectangle_selector.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def toggle_selector(event):
4646
drawtype='box', useblit=True,
4747
button=[1, 3], # don't use middle button
4848
minspanx=5, minspany=5,
49-
spancoords='pixels')
49+
spancoords='pixels',
50+
interactive=True)
5051
plt.connect('key_press_event', toggle_selector)
5152
plt.show()

lib/matplotlib/tests/test_widgets.py

Lines changed: 126 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,18 @@
1111
import matplotlib.pyplot as plt
1212
from matplotlib.testing.decorators import cleanup
1313

14+
from numpy.testing import assert_allclose
1415

15-
def get_event(ax, button=1, xdata=0, ydata=0, key=None, step=1):
16+
17+
def get_ax():
18+
fig, ax = plt.subplots(1, 1)
19+
ax.plot([0, 200], [0, 200])
20+
ax.set_aspect(1.0)
21+
ax.figure.canvas.draw()
22+
return ax
23+
24+
25+
def do_event(tool, etype, button=1, xdata=0, ydata=0, key=None, step=1):
1626
"""
1727
*name*
1828
the event name
@@ -51,6 +61,7 @@ def get_event(ax, button=1, xdata=0, ydata=0, key=None, step=1):
5161
"""
5262
event = mock.Mock()
5363
event.button = button
64+
ax = tool.ax
5465
event.x, event.y = ax.transData.transform([(xdata, ydata),
5566
(xdata, ydata)])[00]
5667
event.xdata, event.ydata = xdata, ydata
@@ -60,32 +71,33 @@ def get_event(ax, button=1, xdata=0, ydata=0, key=None, step=1):
6071
event.step = step
6172
event.guiEvent = None
6273
event.name = 'Custom'
63-
return event
74+
75+
func = getattr(tool, etype)
76+
func(event)
6477

6578

6679
@cleanup
6780
def check_rectangle(**kwargs):
68-
fig, ax = plt.subplots(1, 1)
69-
ax.plot([0, 200], [0, 200])
70-
ax.figure.canvas.draw()
81+
ax = get_ax()
7182

7283
def onselect(epress, erelease):
7384
ax._got_onselect = True
7485
assert epress.xdata == 100
7586
assert epress.ydata == 100
76-
assert erelease.xdata == 200
77-
assert erelease.ydata == 200
87+
assert erelease.xdata == 199
88+
assert erelease.ydata == 199
7889

7990
tool = widgets.RectangleSelector(ax, onselect, **kwargs)
80-
event = get_event(ax, xdata=100, ydata=100, button=1)
81-
tool.press(event)
82-
83-
event = get_event(ax, xdata=125, ydata=125, button=1)
84-
tool.onmove(event)
91+
do_event(tool, 'press', xdata=100, ydata=100, button=1)
92+
do_event(tool, 'onmove', xdata=199, ydata=199, button=1)
8593

8694
# purposely drag outside of axis for release
87-
event = get_event(ax, xdata=250, ydata=250, button=1)
88-
tool.release(event)
95+
do_event(tool, 'release', xdata=250, ydata=250, button=1)
96+
97+
if kwargs.get('drawtype', None) not in ['line', 'none']:
98+
assert_allclose(tool.geometry,
99+
[[100., 100, 199, 199, 100], [100, 199, 199, 100, 100]],
100+
err_msg=tool.geometry)
89101

90102
assert ax._got_onselect
91103

@@ -99,11 +111,101 @@ def test_rectangle_selector():
99111
check_rectangle(rectprops=dict(fill=True))
100112

101113

114+
@cleanup
115+
def test_ellipse():
116+
"""For ellipse, test out the key modifiers"""
117+
ax = get_ax()
118+
119+
def onselect(epress, erelease):
120+
pass
121+
122+
tool = widgets.EllipseSelector(ax, onselect=onselect,
123+
maxdist=10, interactive=True)
124+
tool.extents = (100, 150, 100, 150)
125+
126+
# drag the rectangle
127+
do_event(tool, 'press', xdata=10, ydata=10, button=1,
128+
key=' ')
129+
do_event(tool, 'onmove', xdata=30, ydata=30, button=1)
130+
do_event(tool, 'release', xdata=30, ydata=30, button=1)
131+
assert tool.extents == (120, 170, 120, 170), tool.extents
132+
133+
# create from center
134+
do_event(tool, 'on_key_press', xdata=100, ydata=100, button=1,
135+
key='control')
136+
do_event(tool, 'press', xdata=100, ydata=100, button=1)
137+
do_event(tool, 'onmove', xdata=125, ydata=125, button=1)
138+
do_event(tool, 'release', xdata=125, ydata=125, button=1)
139+
do_event(tool, 'on_key_release', xdata=100, ydata=100, button=1,
140+
key='control')
141+
assert tool.extents == (75, 125, 75, 125), tool.extents
142+
143+
# create a square
144+
do_event(tool, 'on_key_press', xdata=10, ydata=10, button=1,
145+
key='shift')
146+
do_event(tool, 'press', xdata=10, ydata=10, button=1)
147+
do_event(tool, 'onmove', xdata=35, ydata=30, button=1)
148+
do_event(tool, 'release', xdata=35, ydata=30, button=1)
149+
do_event(tool, 'on_key_release', xdata=10, ydata=10, button=1,
150+
key='shift')
151+
extents = [int(e) for e in tool.extents]
152+
assert extents == [10, 35, 10, 34]
153+
154+
# create a square from center
155+
do_event(tool, 'on_key_press', xdata=100, ydata=100, button=1,
156+
key='ctrl+shift')
157+
do_event(tool, 'press', xdata=100, ydata=100, button=1)
158+
do_event(tool, 'onmove', xdata=125, ydata=130, button=1)
159+
do_event(tool, 'release', xdata=125, ydata=130, button=1)
160+
do_event(tool, 'on_key_release', xdata=100, ydata=100, button=1,
161+
key='ctrl+shift')
162+
extents = [int(e) for e in tool.extents]
163+
assert extents == [70, 129, 70, 130], extents
164+
165+
assert tool.geometry.shape == (2, 74)
166+
assert_allclose(tool.geometry[:, 0], [70., 100])
167+
168+
169+
@cleanup
170+
def test_rectangle_handles():
171+
ax = get_ax()
172+
173+
def onselect(epress, erelease):
174+
pass
175+
176+
tool = widgets.RectangleSelector(ax, onselect=onselect,
177+
maxdist=10, interactive=True)
178+
tool.extents = (100, 150, 100, 150)
179+
180+
assert tool.corners == (
181+
(100, 150, 150, 100), (100, 100, 150, 150))
182+
assert tool.extents == (100, 150, 100, 150)
183+
assert tool.edge_centers == (
184+
(100, 125.0, 150, 125.0), (125.0, 100, 125.0, 150))
185+
assert tool.extents == (100, 150, 100, 150)
186+
187+
# grab a corner and move it
188+
do_event(tool, 'press', xdata=100, ydata=100)
189+
do_event(tool, 'onmove', xdata=120, ydata=120)
190+
do_event(tool, 'release', xdata=120, ydata=120)
191+
assert tool.extents == (120, 150, 120, 150)
192+
193+
# grab the center and move it
194+
do_event(tool, 'press', xdata=132, ydata=132)
195+
do_event(tool, 'onmove', xdata=120, ydata=120)
196+
do_event(tool, 'release', xdata=120, ydata=120)
197+
assert tool.extents == (108, 138, 108, 138)
198+
199+
# create a new rectangle
200+
do_event(tool, 'press', xdata=10, ydata=10)
201+
do_event(tool, 'onmove', xdata=100, ydata=100)
202+
do_event(tool, 'release', xdata=100, ydata=100)
203+
assert tool.extents == (10, 100, 10, 100)
204+
205+
102206
@cleanup
103207
def check_span(*args, **kwargs):
104-
fig, ax = plt.subplots(1, 1)
105-
ax.plot([0, 200], [0, 200])
106-
ax.figure.canvas.draw()
208+
ax = get_ax()
107209

108210
def onselect(vmin, vmax):
109211
ax._got_onselect = True
@@ -119,14 +221,9 @@ def onmove(vmin, vmax):
119221
kwargs['onmove_callback'] = onmove
120222

121223
tool = widgets.SpanSelector(ax, onselect, *args, **kwargs)
122-
event = get_event(ax, xdata=100, ydata=100, button=1)
123-
tool.press(event)
124-
125-
event = get_event(ax, xdata=125, ydata=125, button=1)
126-
tool.onmove(event)
127-
128-
event = get_event(ax, xdata=150, ydata=150, button=1)
129-
tool.release(event)
224+
do_event(tool, 'press', xdata=100, ydata=100, button=1)
225+
do_event(tool, 'onmove', xdata=125, ydata=125, button=1)
226+
do_event(tool, 'release', xdata=150, ydata=150, button=1)
130227

131228
assert ax._got_onselect
132229

@@ -142,24 +239,16 @@ def test_span_selector():
142239

143240
@cleanup
144241
def check_lasso_selector(**kwargs):
145-
fig, ax = plt.subplots(1, 1)
146-
ax = plt.gca()
147-
ax.plot([0, 200], [0, 200])
148-
ax.figure.canvas.draw()
242+
ax = get_ax()
149243

150244
def onselect(verts):
151245
ax._got_onselect = True
152246
assert verts == [(100, 100), (125, 125), (150, 150)]
153247

154248
tool = widgets.LassoSelector(ax, onselect, **kwargs)
155-
event = get_event(ax, xdata=100, ydata=100, button=1)
156-
tool.press(event)
157-
158-
event = get_event(ax, xdata=125, ydata=125, button=1)
159-
tool.onmove(event)
160-
161-
event = get_event(ax, xdata=150, ydata=150, button=1)
162-
tool.release(event)
249+
do_event(tool, 'press', xdata=100, ydata=100, button=1)
250+
do_event(tool, 'onmove', xdata=125, ydata=125, button=1)
251+
do_event(tool, 'release', xdata=150, ydata=150, button=1)
163252

164253
assert ax._got_onselect
165254

0 commit comments

Comments
 (0)