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

Skip to content

Commit 161e01d

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

File tree

1 file changed

+65
-44
lines changed

1 file changed

+65
-44
lines changed

lib/matplotlib/tests/test_widgets.py

Lines changed: 65 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -84,19 +84,20 @@ def test_rectangle_selector(ax, kwargs):
8484

8585
# purposely drag outside of axis for release
8686
do_event(tool, 'release', xdata=250, ydata=250, button=1)
87+
do_event(tool, 'onmove', xdata=250, ydata=250, button=1)
8788

8889
if kwargs.get('drawtype', None) not in ['line', 'none']:
8990
assert_allclose(tool.geometry,
90-
[[100., 100, 199, 199, 100],
91+
[[100, 100, 199, 199, 100],
9192
[100, 199, 199, 100, 100]],
9293
err_msg=tool.geometry)
9394

9495
onselect.assert_called_once()
9596
(epress, erelease), kwargs = onselect.call_args
9697
assert epress.xdata == 100
9798
assert epress.ydata == 100
98-
assert erelease.xdata == 199
99-
assert erelease.ydata == 199
99+
assert erelease.xdata == 200
100+
assert erelease.ydata == 200
100101
assert kwargs == {}
101102

102103

@@ -193,10 +194,16 @@ def test_rectangle_selector_set_props_handle_props(ax):
193194
assert artist.get_alpha() == 0.3
194195

195196

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

202209
# resize NE handle
@@ -317,16 +324,16 @@ def test_rectangle_resize_center(ax, add_state):
317324
xdata_new, ydata_new = xdata + xdiff, ydata + ydiff
318325
click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new),
319326
key=use_key)
320-
assert tool.extents == (xdata_new, extents[1] - xdiff,
321-
ydata_new, extents[3] - ydiff)
327+
assert_allclose(tool.extents, (xdata_new, extents[1] - xdiff,
328+
ydata_new, extents[3] - ydiff))
322329

323330

324331
@pytest.mark.parametrize('add_state', [True, False])
325332
def test_rectangle_resize_square(ax, add_state):
326333
tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True)
327334
# Create rectangle
328335
click_and_drag(tool, start=(70, 65), end=(120, 115))
329-
assert tool.extents == (70.0, 120.0, 65.0, 115.0)
336+
assert_allclose(tool.extents, (70.0, 120.0, 65.0, 115.0))
330337

331338
if add_state:
332339
tool.add_state('square')
@@ -341,8 +348,8 @@ def test_rectangle_resize_square(ax, add_state):
341348
xdata_new, ydata_new = xdata + xdiff, ydata + ydiff
342349
click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new),
343350
key=use_key)
344-
assert tool.extents == (extents[0], xdata_new,
345-
extents[2], extents[3] + xdiff)
351+
assert_allclose(tool.extents, (extents[0], xdata_new,
352+
extents[2], extents[3] + xdiff))
346353

347354
# resize E handle
348355
extents = tool.extents
@@ -391,11 +398,12 @@ def test_rectangle_resize_square(ax, add_state):
391398
xdata_new, ydata_new = xdata + xdiff, ydata + ydiff
392399
click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new),
393400
key=use_key)
394-
assert_allclose(tool.extents, (extents[0] + ydiff, extents[1],
395-
ydata_new, extents[3]))
401+
assert_allclose(tool.extents, (xdata_new, extents[1],
402+
extents[2] + xdiff, extents[3]))
396403

397404

398405
def test_rectangle_resize_square_center(ax):
406+
ax.set_aspect(1)
399407
tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True)
400408
# Create rectangle
401409
click_and_drag(tool, start=(70, 65), end=(120, 115))
@@ -461,6 +469,7 @@ def test_rectangle_resize_square_center(ax):
461469
@pytest.mark.parametrize('selector_class',
462470
[widgets.RectangleSelector, widgets.EllipseSelector])
463471
def test_rectangle_rotate(ax, selector_class):
472+
ax.set_aspect(1)
464473
tool = selector_class(ax, onselect=noop, interactive=True)
465474
# Draw rectangle
466475
click_and_drag(tool, start=(100, 100), end=(130, 140))
@@ -474,19 +483,19 @@ def test_rectangle_rotate(ax, selector_class):
474483
click_and_drag(tool, start=(130, 140), end=(120, 145))
475484
do_event(tool, 'on_key_press', key='r')
476485
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)
486+
# Extents change as the selector remains rigid in display coordinates
487+
assert_allclose(tool.extents, (110.10, 119.90, 95.49, 144.51), atol=0.01)
479488
assert_allclose(tool.rotation, 25.56, atol=0.01)
480489
tool.rotation = 45
481490
assert tool.rotation == 45
482491
# Corners should move
483492
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)
493+
np.array([[110.10, 131.31, 103.03, 81.81],
494+
[95.49, 116.70, 144.98, 123.77]]), atol=0.01)
486495

487496
# Scale using top-right corner
488497
click_and_drag(tool, start=(110, 145), end=(110, 160))
489-
assert_allclose(tool.extents, (100, 139.75, 100, 151.82), atol=0.01)
498+
assert_allclose(tool.extents, (110, 110, 145, 160), atol=0.01)
490499

491500
if selector_class == widgets.RectangleSelector:
492501
with pytest.raises(ValueError):
@@ -508,36 +517,38 @@ def test_rectangle_add_remove_set(ax):
508517

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

513525
tool = widgets.RectangleSelector(ax, onselect=noop, interactive=True,
514526
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))
518527
tool.add_state('square')
519528
tool.add_state('center')
529+
# Create rectangle, width 50 in data coordinates
530+
click_and_drag(tool, start=(70, 65), end=(120, 75))
520531

521532
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])
533+
assert_allclose(tool.extents, (20, 120, 15, 115))
531534
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])
535+
assert_allclose(tool.extents, (20, 120, -35, 165))
536+
537+
# resize E handle
538+
extents = tool.extents
539+
xdata, ydata = extents[1], extents[3]
540+
xdiff = 10
541+
xdata_new, ydata_new = xdata + xdiff, ydata
542+
if use_data_coordinates:
543+
# In data coordinates the difference should be equal in both directions
544+
ydiff = xdiff
545+
else:
546+
# In display coordinates, the change in data coordinates should be
547+
# different in each direction
548+
ydiff = xdiff / tool.ax._get_aspect_ratio()
549+
click_and_drag(tool, start=(xdata, ydata), end=(xdata_new, ydata_new))
550+
assert_allclose(tool.extents, [extents[0] - xdiff, xdata_new,
551+
extents[2] - ydiff, extents[3] + ydiff])
541552

542553

543554
def test_ellipse(ax):
@@ -1644,6 +1655,7 @@ def test_polygon_selector_verts_setter(fig_test, fig_ref, draw_bounding_box):
16441655
]
16451656
for (etype, event_args) in event_sequence:
16461657
do_event(tool_ref, etype, **event_args)
1658+
np.testing.assert_allclose(tool_ref.verts, verts)
16471659

16481660

16491661
def test_polygon_selector_box(ax):
@@ -1658,10 +1670,19 @@ def test_polygon_selector_box(ax):
16581670
*polygon_place_vertex(*verts[0]),
16591671
]
16601672

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

16661687
# In order to trigger the correct callbacks, trigger events on the canvas
16671688
# instead of the individual tools
@@ -1676,7 +1697,7 @@ def test_polygon_selector_box(ax):
16761697
MouseEvent(
16771698
"button_release_event", canvas, *t.transform((20, 20)), 1)._process()
16781699
np.testing.assert_allclose(
1679-
tool.verts, [(10, 0), (0, 10), (10, 20), (20, 10)])
1700+
tool.verts, [(10, 0), (0, 10), (10, 20), (20, 10)], atol=atol)
16801701

16811702
# Move using the center of the bounding box
16821703
MouseEvent(
@@ -1686,20 +1707,20 @@ def test_polygon_selector_box(ax):
16861707
MouseEvent(
16871708
"button_release_event", canvas, *t.transform((30, 30)), 1)._process()
16881709
np.testing.assert_allclose(
1689-
tool.verts, [(30, 20), (20, 30), (30, 40), (40, 30)])
1710+
tool.verts, [(30, 20), (20, 30), (30, 40), (40, 30)], atol=atol)
16901711

16911712
# Remove a point from the polygon and check that the box extents update
16921713
np.testing.assert_allclose(
1693-
tool._box.extents, (20.0, 40.0, 20.0, 40.0))
1714+
tool._box.extents, (20.0, 40.0, 20.0, 40.0), atol=atol)
16941715

16951716
MouseEvent(
16961717
"button_press_event", canvas, *t.transform((30, 20)), 3)._process()
16971718
MouseEvent(
16981719
"button_release_event", canvas, *t.transform((30, 20)), 3)._process()
16991720
np.testing.assert_allclose(
1700-
tool.verts, [(20, 30), (30, 40), (40, 30)])
1721+
tool.verts, [(20, 30), (30, 40), (40, 30)], atol=atol)
17011722
np.testing.assert_allclose(
1702-
tool._box.extents, (20.0, 40.0, 30.0, 40.0))
1723+
tool._box.extents, (20.0, 40.0, 30.0, 40.0), atol=atol)
17031724

17041725

17051726
def test_polygon_selector_clear_method(ax):

0 commit comments

Comments
 (0)