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

Skip to content

Commit 2c9919c

Browse files
dhomeierdstansby
andcommitted
Rectangle resize tests with multiple start/end corners
Co-authored-by: David Stansby <[email protected]>
1 parent 0484b1d commit 2c9919c

File tree

1 file changed

+65
-45
lines changed

1 file changed

+65
-45
lines changed

lib/matplotlib/tests/test_widgets.py

Lines changed: 65 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import pytest
1919

20-
2120
@pytest.fixture
2221
def ax():
2322
return get_ax()
@@ -84,19 +83,20 @@ def test_rectangle_selector(ax, kwargs):
8483

8584
# purposely drag outside of axis for release
8685
do_event(tool, 'release', xdata=250, ydata=250, button=1)
86+
do_event(tool, 'onmove', xdata=250, ydata=250, button=1)
8787

8888
if kwargs.get('drawtype', None) not in ['line', 'none']:
8989
assert_allclose(tool.geometry,
90-
[[100., 100, 199, 199, 100],
90+
[[100, 100, 199, 199, 100],
9191
[100, 199, 199, 100, 100]],
9292
err_msg=tool.geometry)
9393

9494
onselect.assert_called_once()
9595
(epress, erelease), kwargs = onselect.call_args
9696
assert epress.xdata == 100
9797
assert epress.ydata == 100
98-
assert erelease.xdata == 199
99-
assert erelease.ydata == 199
98+
assert erelease.xdata == 200
99+
assert erelease.ydata == 200
100100
assert kwargs == {}
101101

102102

@@ -193,10 +193,16 @@ def test_rectangle_selector_set_props_handle_props(ax):
193193
assert artist.get_alpha() == 0.3
194194

195195

196-
def test_rectangle_resize(ax):
196+
# Should give same results if rectangle is created from any two
197+
# opposite corners
198+
@pytest.mark.parametrize('start, end', [[(0, 10), (100, 120)],
199+
[(100, 120), (0, 10)],
200+
[(0, 120), (100, 10)],
201+
[(100, 10), (0, 120)]])
202+
def test_rectangle_resize(ax, start, end):
197203
tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True)
198204
# Create rectangle
199-
click_and_drag(tool, start=(0, 10), end=(100, 120))
205+
click_and_drag(tool, start=start, end=end)
200206
assert_allclose(tool.extents, (0.0, 100.0, 10.0, 120.0))
201207

202208
# resize NE handle
@@ -317,16 +323,16 @@ def test_rectangle_resize_center(ax, add_state):
317323
xdata_new, ydata_new = xdata + xdiff, ydata + ydiff
318324
click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new),
319325
key=use_key)
320-
assert tool.extents == (xdata_new, extents[1] - xdiff,
321-
ydata_new, extents[3] - ydiff)
326+
assert_allclose(tool.extents, (xdata_new, extents[1] - xdiff,
327+
ydata_new, extents[3] - ydiff))
322328

323329

324330
@pytest.mark.parametrize('add_state', [True, False])
325331
def test_rectangle_resize_square(ax, add_state):
326332
tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True)
327333
# Create rectangle
328334
click_and_drag(tool, start=(70, 65), end=(120, 115))
329-
assert tool.extents == (70.0, 120.0, 65.0, 115.0)
335+
assert_allclose(tool.extents, (70.0, 120.0, 65.0, 115.0))
330336

331337
if add_state:
332338
tool.add_state('square')
@@ -341,8 +347,8 @@ def test_rectangle_resize_square(ax, add_state):
341347
xdata_new, ydata_new = xdata + xdiff, ydata + ydiff
342348
click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new),
343349
key=use_key)
344-
assert tool.extents == (extents[0], xdata_new,
345-
extents[2], extents[3] + xdiff)
350+
assert_allclose(tool.extents, (extents[0], xdata_new,
351+
extents[2], extents[3] + xdiff))
346352

347353
# resize E handle
348354
extents = tool.extents
@@ -391,11 +397,12 @@ def test_rectangle_resize_square(ax, add_state):
391397
xdata_new, ydata_new = xdata + xdiff, ydata + ydiff
392398
click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new),
393399
key=use_key)
394-
assert_allclose(tool.extents, (extents[0] + ydiff, extents[1],
395-
ydata_new, extents[3]))
400+
assert_allclose(tool.extents, (xdata_new, extents[1],
401+
extents[2] + xdiff, extents[3]))
396402

397403

398404
def test_rectangle_resize_square_center(ax):
405+
ax.set_aspect(1)
399406
tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True)
400407
# Create rectangle
401408
click_and_drag(tool, start=(70, 65), end=(120, 115))
@@ -461,6 +468,7 @@ def test_rectangle_resize_square_center(ax):
461468
@pytest.mark.parametrize('selector_class',
462469
[widgets.RectangleSelector, widgets.EllipseSelector])
463470
def test_rectangle_rotate(ax, selector_class):
471+
ax.set_aspect(1)
464472
tool = selector_class(ax, onselect=noop, interactive=True)
465473
# Draw rectangle
466474
click_and_drag(tool, start=(100, 100), end=(130, 140))
@@ -474,19 +482,19 @@ def test_rectangle_rotate(ax, selector_class):
474482
click_and_drag(tool, start=(130, 140), end=(120, 145))
475483
do_event(tool, 'on_key_press', key='r')
476484
assert len(tool._state) == 0
477-
# Extents shouldn't change (as shape of rectangle hasn't changed)
478-
assert tool.extents == (100, 130, 100, 140)
485+
# Extents change as the selector remains rigid in display coordinates
486+
assert_allclose(tool.extents, (110.10, 119.90, 95.49, 144.51), atol=0.01)
479487
assert_allclose(tool.rotation, 25.56, atol=0.01)
480488
tool.rotation = 45
481489
assert tool.rotation == 45
482490
# Corners should move
483491
assert_allclose(tool.corners,
484-
np.array([[118.53, 139.75, 111.46, 90.25],
485-
[95.25, 116.46, 144.75, 123.54]]), atol=0.01)
492+
np.array([[110.10, 131.31, 103.03, 81.81],
493+
[95.49, 116.70, 144.98, 123.77]]), atol=0.01)
486494

487495
# Scale using top-right corner
488496
click_and_drag(tool, start=(110, 145), end=(110, 160))
489-
assert_allclose(tool.extents, (100, 139.75, 100, 151.82), atol=0.01)
497+
assert_allclose(tool.extents, (110, 110, 145, 160), atol=0.01)
490498

491499
if selector_class == widgets.RectangleSelector:
492500
with pytest.raises(ValueError):
@@ -508,36 +516,38 @@ def test_rectangle_add_remove_set(ax):
508516

509517
@pytest.mark.parametrize('use_data_coordinates', [False, True])
510518
def test_rectangle_resize_square_center_aspect(ax, use_data_coordinates):
511-
ax.set_aspect(0.8)
519+
ax = get_ax()
520+
ax.set_aspect(0.5)
521+
# Need to call a draw to update ax.transData
522+
plt.gcf().canvas.draw()
512523

513524
tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True,
514525
use_data_coordinates=use_data_coordinates)
515-
# Create rectangle
516-
click_and_drag(tool, start=(70, 65), end=(120, 115))
517-
assert_allclose(tool.extents, (70.0, 120.0, 65.0, 115.0))
518526
tool.add_state('square')
519527
tool.add_state('center')
528+
# Create rectangle, width 50 in data coordinates
529+
click_and_drag(tool, start=(70, 65), end=(120, 75))
520530

521531
if use_data_coordinates:
522-
# resize E handle
523-
extents = tool.extents
524-
xdata, ydata, width = extents[1], extents[3], extents[1] - extents[0]
525-
xdiff, ycenter = 10, extents[2] + (extents[3] - extents[2]) / 2
526-
xdata_new, ydata_new = xdata + xdiff, ydata
527-
ychange = width / 2 + xdiff
528-
click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new))
529-
assert_allclose(tool.extents, [extents[0] - xdiff, xdata_new,
530-
ycenter - ychange, ycenter + ychange])
532+
assert_allclose(tool.extents, (20, 120, 15, 115))
531533
else:
532-
# resize E handle
533-
extents = tool.extents
534-
xdata, ydata = extents[1], extents[3]
535-
xdiff = 10
536-
xdata_new, ydata_new = xdata + xdiff, ydata
537-
ychange = xdiff * 1 / tool._aspect_ratio_correction
538-
click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new))
539-
assert_allclose(tool.extents, [extents[0] - xdiff, xdata_new,
540-
46.25, 133.75])
534+
assert_allclose(tool.extents, (20, 120, -35, 165))
535+
536+
# resize E handle
537+
extents = tool.extents
538+
xdata, ydata = extents[1], extents[3]
539+
xdiff = 10
540+
xdata_new, ydata_new = xdata + xdiff, ydata
541+
if use_data_coordinates:
542+
# In data coordinates the difference should be equal in both directions
543+
ydiff = xdiff
544+
else:
545+
# In display coordinates, the change in data coordinates should be
546+
# different in each direction
547+
ydiff = xdiff / tool.ax._get_aspect_ratio()
548+
click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new))
549+
assert_allclose(tool.extents, [extents[0] - xdiff, xdata_new,
550+
extents[2] - ydiff, extents[3] + ydiff])
541551

542552

543553
def test_ellipse(ax):
@@ -1644,6 +1654,7 @@ def test_polygon_selector_verts_setter(fig_test, fig_ref, draw_bounding_box):
16441654
]
16451655
for (etype, event_args) in event_sequence:
16461656
do_event(tool_ref, etype, **event_args)
1657+
np.testing.assert_allclose(tool_ref.verts, verts)
16471658

16481659

16491660
def test_polygon_selector_box(ax):
@@ -1658,10 +1669,19 @@ def test_polygon_selector_box(ax):
16581669
*polygon_place_vertex(*verts[0]),
16591670
]
16601671

1672+
# Set smaller axes limits to reduce errors in converting from data to
1673+
# display coords. The canvas size is 640 x 640, so we need a tolerance of
1674+
# (data width / canvas width) = 50 / 640 ~ 0.08 when comparing points in
1675+
# data space
1676+
ax.set_xlim(-5, 45)
1677+
ax.set_ylim(-5, 45)
1678+
atol = 0.08
1679+
16611680
# Create selector
16621681
tool = widgets.PolygonSelector(ax, onselect=noop, draw_bounding_box=True)
16631682
for (etype, event_args) in event_sequence:
16641683
do_event(tool, etype, **event_args)
1684+
np.testing.assert_allclose(tool.verts, verts, atol=atol)
16651685

16661686
# In order to trigger the correct callbacks, trigger events on the canvas
16671687
# instead of the individual tools
@@ -1676,7 +1696,7 @@ def test_polygon_selector_box(ax):
16761696
MouseEvent(
16771697
"button_release_event", canvas, *t.transform((20, 20)), 1)._process()
16781698
np.testing.assert_allclose(
1679-
tool.verts, [(10, 0), (0, 10), (10, 20), (20, 10)])
1699+
tool.verts, [(10, 0), (0, 10), (10, 20), (20, 10)], atol=atol)
16801700

16811701
# Move using the center of the bounding box
16821702
MouseEvent(
@@ -1686,20 +1706,20 @@ def test_polygon_selector_box(ax):
16861706
MouseEvent(
16871707
"button_release_event", canvas, *t.transform((30, 30)), 1)._process()
16881708
np.testing.assert_allclose(
1689-
tool.verts, [(30, 20), (20, 30), (30, 40), (40, 30)])
1709+
tool.verts, [(30, 20), (20, 30), (30, 40), (40, 30)], atol=atol)
16901710

16911711
# Remove a point from the polygon and check that the box extents update
16921712
np.testing.assert_allclose(
1693-
tool._box.extents, (20.0, 40.0, 20.0, 40.0))
1713+
tool._box.extents, (20.0, 40.0, 20.0, 40.0), atol=atol)
16941714

16951715
MouseEvent(
16961716
"button_press_event", canvas, *t.transform((30, 20)), 3)._process()
16971717
MouseEvent(
16981718
"button_release_event", canvas, *t.transform((30, 20)), 3)._process()
16991719
np.testing.assert_allclose(
1700-
tool.verts, [(20, 30), (30, 40), (40, 30)])
1720+
tool.verts, [(20, 30), (30, 40), (40, 30)], atol=atol)
17011721
np.testing.assert_allclose(
1702-
tool._box.extents, (20.0, 40.0, 30.0, 40.0))
1722+
tool._box.extents, (20.0, 40.0, 30.0, 40.0), atol=atol)
17031723

17041724

17051725
def test_polygon_selector_clear_method(ax):

0 commit comments

Comments
 (0)