@@ -82,19 +82,20 @@ def test_rectangle_selector(ax, kwargs):
82
82
83
83
# purposely drag outside of axis for release
84
84
do_event (tool , 'release' , xdata = 250 , ydata = 250 , button = 1 )
85
+ do_event (tool , 'onmove' , xdata = 250 , ydata = 250 , button = 1 )
85
86
86
87
if kwargs .get ('drawtype' , None ) not in ['line' , 'none' ]:
87
88
assert_allclose (tool .geometry ,
88
- [[100. , 100 , 199 , 199 , 100 ],
89
+ [[100 , 100 , 199 , 199 , 100 ],
89
90
[100 , 199 , 199 , 100 , 100 ]],
90
91
err_msg = tool .geometry )
91
92
92
93
onselect .assert_called_once ()
93
94
(epress , erelease ), kwargs = onselect .call_args
94
95
assert epress .xdata == 100
95
96
assert epress .ydata == 100
96
- assert erelease .xdata == 199
97
- assert erelease .ydata == 199
97
+ assert erelease .xdata == 200
98
+ assert erelease .ydata == 200
98
99
assert kwargs == {}
99
100
100
101
@@ -191,10 +192,16 @@ def test_rectangle_selector_set_props_handle_props(ax):
191
192
assert artist .get_alpha () == 0.3
192
193
193
194
194
- def test_rectangle_resize (ax ):
195
+ # Should give same results if rectangle is created from any two
196
+ # opposite corners
197
+ @pytest .mark .parametrize ('start, end' , [[(0 , 10 ), (100 , 120 )],
198
+ [(100 , 120 ), (0 , 10 )],
199
+ [(0 , 120 ), (100 , 10 )],
200
+ [(100 , 10 ), (0 , 120 )]])
201
+ def test_rectangle_resize (ax , start , end ):
195
202
tool = widgets .RectangleSelector (ax , onselect = noop , interactive = True )
196
203
# Create rectangle
197
- click_and_drag (tool , start = ( 0 , 10 ), end = ( 100 , 120 ) )
204
+ click_and_drag (tool , start = start , end = end )
198
205
assert_allclose (tool .extents , (0.0 , 100.0 , 10.0 , 120.0 ))
199
206
200
207
# resize NE handle
@@ -315,16 +322,16 @@ def test_rectangle_resize_center(ax, add_state):
315
322
xdata_new , ydata_new = xdata + xdiff , ydata + ydiff
316
323
click_and_drag (tool , start = (xdata , ydata ), end = (xdata_new , ydata_new ),
317
324
key = use_key )
318
- assert tool .extents == (xdata_new , extents [1 ] - xdiff ,
319
- ydata_new , extents [3 ] - ydiff )
325
+ assert_allclose ( tool .extents , (xdata_new , extents [1 ] - xdiff ,
326
+ ydata_new , extents [3 ] - ydiff ) )
320
327
321
328
322
329
@pytest .mark .parametrize ('add_state' , [True , False ])
323
330
def test_rectangle_resize_square (ax , add_state ):
324
331
tool = widgets .RectangleSelector (ax , onselect = noop , interactive = True )
325
332
# Create rectangle
326
333
click_and_drag (tool , start = (70 , 65 ), end = (120 , 115 ))
327
- assert tool .extents == (70.0 , 120.0 , 65.0 , 115.0 )
334
+ assert_allclose ( tool .extents , (70.0 , 120.0 , 65.0 , 115.0 ) )
328
335
329
336
if add_state :
330
337
tool .add_state ('square' )
@@ -339,8 +346,8 @@ def test_rectangle_resize_square(ax, add_state):
339
346
xdata_new , ydata_new = xdata + xdiff , ydata + ydiff
340
347
click_and_drag (tool , start = (xdata , ydata ), end = (xdata_new , ydata_new ),
341
348
key = use_key )
342
- assert tool .extents == (extents [0 ], xdata_new ,
343
- extents [2 ], extents [3 ] + xdiff )
349
+ assert_allclose ( tool .extents , (extents [0 ], xdata_new ,
350
+ extents [2 ], extents [3 ] + xdiff ) )
344
351
345
352
# resize E handle
346
353
extents = tool .extents
@@ -389,11 +396,12 @@ def test_rectangle_resize_square(ax, add_state):
389
396
xdata_new , ydata_new = xdata + xdiff , ydata + ydiff
390
397
click_and_drag (tool , start = (xdata , ydata ), end = (xdata_new , ydata_new ),
391
398
key = use_key )
392
- assert_allclose (tool .extents , (extents [ 0 ] + ydiff , extents [1 ],
393
- ydata_new , extents [3 ]))
399
+ assert_allclose (tool .extents , (xdata_new , extents [1 ],
400
+ extents [ 2 ] + xdiff , extents [3 ]))
394
401
395
402
396
403
def test_rectangle_resize_square_center (ax ):
404
+ ax .set_aspect (1 )
397
405
tool = widgets .RectangleSelector (ax , onselect = noop , interactive = True )
398
406
# Create rectangle
399
407
click_and_drag (tool , start = (70 , 65 ), end = (120 , 115 ))
@@ -459,6 +467,7 @@ def test_rectangle_resize_square_center(ax):
459
467
@pytest .mark .parametrize ('selector_class' ,
460
468
[widgets .RectangleSelector , widgets .EllipseSelector ])
461
469
def test_rectangle_rotate (ax , selector_class ):
470
+ ax .set_aspect (1 )
462
471
tool = selector_class (ax , onselect = noop , interactive = True )
463
472
# Draw rectangle
464
473
click_and_drag (tool , start = (100 , 100 ), end = (130 , 140 ))
@@ -472,19 +481,19 @@ def test_rectangle_rotate(ax, selector_class):
472
481
click_and_drag (tool , start = (130 , 140 ), end = (120 , 145 ))
473
482
do_event (tool , 'on_key_press' , key = 'r' )
474
483
assert len (tool ._state ) == 0
475
- # Extents shouldn't change ( as shape of rectangle hasn't changed)
476
- assert tool .extents == ( 100 , 130 , 100 , 140 )
484
+ # Extents change as the selector remains rigid in display coordinates
485
+ assert_allclose ( tool .extents , ( 110.10 , 119.90 , 95.49 , 144.51 ), atol = 0.01 )
477
486
assert_allclose (tool .rotation , 25.56 , atol = 0.01 )
478
487
tool .rotation = 45
479
488
assert tool .rotation == 45
480
489
# Corners should move
481
490
assert_allclose (tool .corners ,
482
- np .array ([[118.53 , 139.75 , 111.46 , 90.25 ],
483
- [95.25 , 116.46 , 144.75 , 123.54 ]]), atol = 0.01 )
491
+ np .array ([[110.10 , 131.31 , 103.03 , 81.81 ],
492
+ [95.49 , 116.70 , 144.98 , 123.77 ]]), atol = 0.01 )
484
493
485
494
# Scale using top-right corner
486
495
click_and_drag (tool , start = (110 , 145 ), end = (110 , 160 ))
487
- assert_allclose (tool .extents , (100 , 139.75 , 100 , 151.82 ), atol = 0.01 )
496
+ assert_allclose (tool .extents , (110 , 110 , 145 , 160 ), atol = 0.01 )
488
497
489
498
if selector_class == widgets .RectangleSelector :
490
499
with pytest .raises (ValueError ):
@@ -506,36 +515,38 @@ def test_rectangle_add_remove_set(ax):
506
515
507
516
@pytest .mark .parametrize ('use_data_coordinates' , [False , True ])
508
517
def test_rectangle_resize_square_center_aspect (ax , use_data_coordinates ):
509
- ax .set_aspect (0.8 )
518
+ ax = get_ax ()
519
+ ax .set_aspect (0.5 )
520
+ # Need to call a draw to update ax.transData
521
+ plt .gcf ().canvas .draw ()
510
522
511
523
tool = widgets .RectangleSelector (ax , onselect = noop , interactive = True ,
512
524
use_data_coordinates = use_data_coordinates )
513
- # Create rectangle
514
- click_and_drag (tool , start = (70 , 65 ), end = (120 , 115 ))
515
- assert_allclose (tool .extents , (70.0 , 120.0 , 65.0 , 115.0 ))
516
525
tool .add_state ('square' )
517
526
tool .add_state ('center' )
527
+ # Create rectangle, width 50 in data coordinates
528
+ click_and_drag (tool , start = (70 , 65 ), end = (120 , 75 ))
518
529
519
530
if use_data_coordinates :
520
- # resize E handle
521
- extents = tool .extents
522
- xdata , ydata , width = extents [1 ], extents [3 ], extents [1 ] - extents [0 ]
523
- xdiff , ycenter = 10 , extents [2 ] + (extents [3 ] - extents [2 ]) / 2
524
- xdata_new , ydata_new = xdata + xdiff , ydata
525
- ychange = width / 2 + xdiff
526
- click_and_drag (tool , start = (xdata , ydata ), end = (xdata_new , ydata_new ))
527
- assert_allclose (tool .extents , [extents [0 ] - xdiff , xdata_new ,
528
- ycenter - ychange , ycenter + ychange ])
531
+ assert_allclose (tool .extents , (20 , 120 , 15 , 115 ))
529
532
else :
530
- # resize E handle
531
- extents = tool .extents
532
- xdata , ydata = extents [1 ], extents [3 ]
533
- xdiff = 10
534
- xdata_new , ydata_new = xdata + xdiff , ydata
535
- ychange = xdiff * 1 / tool ._aspect_ratio_correction
536
- click_and_drag (tool , start = (xdata , ydata ), end = (xdata_new , ydata_new ))
537
- assert_allclose (tool .extents , [extents [0 ] - xdiff , xdata_new ,
538
- 46.25 , 133.75 ])
533
+ assert_allclose (tool .extents , (20 , 120 , - 35 , 165 ))
534
+
535
+ # resize E handle
536
+ extents = tool .extents
537
+ xdata , ydata = extents [1 ], extents [3 ]
538
+ xdiff = 10
539
+ xdata_new , ydata_new = xdata + xdiff , ydata
540
+ if use_data_coordinates :
541
+ # In data coordinates the difference should be equal in both directions
542
+ ydiff = xdiff
543
+ else :
544
+ # In display coordinates, the change in data coordinates should be
545
+ # different in each direction
546
+ ydiff = xdiff / tool .ax ._get_aspect_ratio ()
547
+ click_and_drag (tool , start = (xdata , ydata ), end = (xdata_new , ydata_new ))
548
+ assert_allclose (tool .extents , [extents [0 ] - xdiff , xdata_new ,
549
+ extents [2 ] - ydiff , extents [3 ] + ydiff ])
539
550
540
551
541
552
def test_ellipse (ax ):
@@ -1646,6 +1657,7 @@ def test_polygon_selector_verts_setter(fig_test, fig_ref, draw_bounding_box):
1646
1657
]
1647
1658
for (etype , event_args ) in event_sequence :
1648
1659
do_event (tool_ref , etype , ** event_args )
1660
+ np .testing .assert_allclose (tool_ref .verts , verts )
1649
1661
1650
1662
1651
1663
def test_polygon_selector_box (ax ):
@@ -1660,10 +1672,19 @@ def test_polygon_selector_box(ax):
1660
1672
* polygon_place_vertex (* verts [0 ]),
1661
1673
]
1662
1674
1675
+ # Set smaller axes limits to reduce errors in converting from data to
1676
+ # display coords. The canvas size is 640 x 640, so we need a tolerance of
1677
+ # (data width / canvas width) = 50 / 640 ~ 0.08 when comparing points in
1678
+ # data space
1679
+ ax .set_xlim (- 5 , 45 )
1680
+ ax .set_ylim (- 5 , 45 )
1681
+ atol = 0.08
1682
+
1663
1683
# Create selector
1664
1684
tool = widgets .PolygonSelector (ax , onselect = noop , draw_bounding_box = True )
1665
1685
for (etype , event_args ) in event_sequence :
1666
1686
do_event (tool , etype , ** event_args )
1687
+ np .testing .assert_allclose (tool .verts , verts , atol = atol )
1667
1688
1668
1689
# In order to trigger the correct callbacks, trigger events on the canvas
1669
1690
# instead of the individual tools
@@ -1678,7 +1699,7 @@ def test_polygon_selector_box(ax):
1678
1699
MouseEvent (
1679
1700
"button_release_event" , canvas , * t .transform ((20 , 20 )), 1 )._process ()
1680
1701
np .testing .assert_allclose (
1681
- tool .verts , [(10 , 0 ), (0 , 10 ), (10 , 20 ), (20 , 10 )])
1702
+ tool .verts , [(10 , 0 ), (0 , 10 ), (10 , 20 ), (20 , 10 )], atol = atol )
1682
1703
1683
1704
# Move using the center of the bounding box
1684
1705
MouseEvent (
@@ -1688,20 +1709,20 @@ def test_polygon_selector_box(ax):
1688
1709
MouseEvent (
1689
1710
"button_release_event" , canvas , * t .transform ((30 , 30 )), 1 )._process ()
1690
1711
np .testing .assert_allclose (
1691
- tool .verts , [(30 , 20 ), (20 , 30 ), (30 , 40 ), (40 , 30 )])
1712
+ tool .verts , [(30 , 20 ), (20 , 30 ), (30 , 40 ), (40 , 30 )], atol = atol )
1692
1713
1693
1714
# Remove a point from the polygon and check that the box extents update
1694
1715
np .testing .assert_allclose (
1695
- tool ._box .extents , (20.0 , 40.0 , 20.0 , 40.0 ))
1716
+ tool ._box .extents , (20.0 , 40.0 , 20.0 , 40.0 ), atol = atol )
1696
1717
1697
1718
MouseEvent (
1698
1719
"button_press_event" , canvas , * t .transform ((30 , 20 )), 3 )._process ()
1699
1720
MouseEvent (
1700
1721
"button_release_event" , canvas , * t .transform ((30 , 20 )), 3 )._process ()
1701
1722
np .testing .assert_allclose (
1702
- tool .verts , [(20 , 30 ), (30 , 40 ), (40 , 30 )])
1723
+ tool .verts , [(20 , 30 ), (30 , 40 ), (40 , 30 )], atol = atol )
1703
1724
np .testing .assert_allclose (
1704
- tool ._box .extents , (20.0 , 40.0 , 30.0 , 40.0 ))
1725
+ tool ._box .extents , (20.0 , 40.0 , 30.0 , 40.0 ), atol = atol )
1705
1726
1706
1727
1707
1728
def test_polygon_selector_clear_method (ax ):
0 commit comments