@@ -84,19 +84,20 @@ def test_rectangle_selector(ax, kwargs):
84
84
85
85
# purposely drag outside of axis for release
86
86
do_event (tool , 'release' , xdata = 250 , ydata = 250 , button = 1 )
87
+ do_event (tool , 'onmove' , xdata = 250 , ydata = 250 , button = 1 )
87
88
88
89
if kwargs .get ('drawtype' , None ) not in ['line' , 'none' ]:
89
90
assert_allclose (tool .geometry ,
90
- [[100. , 100 , 199 , 199 , 100 ],
91
+ [[100 , 100 , 199 , 199 , 100 ],
91
92
[100 , 199 , 199 , 100 , 100 ]],
92
93
err_msg = tool .geometry )
93
94
94
95
onselect .assert_called_once ()
95
96
(epress , erelease ), kwargs = onselect .call_args
96
97
assert epress .xdata == 100
97
98
assert epress .ydata == 100
98
- assert erelease .xdata == 199
99
- assert erelease .ydata == 199
99
+ assert erelease .xdata == 200
100
+ assert erelease .ydata == 200
100
101
assert kwargs == {}
101
102
102
103
@@ -193,10 +194,16 @@ def test_rectangle_selector_set_props_handle_props(ax):
193
194
assert artist .get_alpha () == 0.3
194
195
195
196
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 ):
197
204
tool = widgets .RectangleSelector (ax , onselect = noop , interactive = True )
198
205
# Create rectangle
199
- click_and_drag (tool , start = ( 0 , 10 ), end = ( 100 , 120 ) )
206
+ click_and_drag (tool , start = start , end = end )
200
207
assert_allclose (tool .extents , (0.0 , 100.0 , 10.0 , 120.0 ))
201
208
202
209
# resize NE handle
@@ -317,16 +324,16 @@ def test_rectangle_resize_center(ax, add_state):
317
324
xdata_new , ydata_new = xdata + xdiff , ydata + ydiff
318
325
click_and_drag (tool , start = (xdata , ydata ), end = (xdata_new , ydata_new ),
319
326
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 ) )
322
329
323
330
324
331
@pytest .mark .parametrize ('add_state' , [True , False ])
325
332
def test_rectangle_resize_square (ax , add_state ):
326
333
tool = widgets .RectangleSelector (ax , onselect = noop , interactive = True )
327
334
# Create rectangle
328
335
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 ) )
330
337
331
338
if add_state :
332
339
tool .add_state ('square' )
@@ -341,8 +348,8 @@ def test_rectangle_resize_square(ax, add_state):
341
348
xdata_new , ydata_new = xdata + xdiff , ydata + ydiff
342
349
click_and_drag (tool , start = (xdata , ydata ), end = (xdata_new , ydata_new ),
343
350
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 ) )
346
353
347
354
# resize E handle
348
355
extents = tool .extents
@@ -391,11 +398,12 @@ def test_rectangle_resize_square(ax, add_state):
391
398
xdata_new , ydata_new = xdata + xdiff , ydata + ydiff
392
399
click_and_drag (tool , start = (xdata , ydata ), end = (xdata_new , ydata_new ),
393
400
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 ]))
396
403
397
404
398
405
def test_rectangle_resize_square_center (ax ):
406
+ ax .set_aspect (1 )
399
407
tool = widgets .RectangleSelector (ax , onselect = noop , interactive = True )
400
408
# Create rectangle
401
409
click_and_drag (tool , start = (70 , 65 ), end = (120 , 115 ))
@@ -461,6 +469,7 @@ def test_rectangle_resize_square_center(ax):
461
469
@pytest .mark .parametrize ('selector_class' ,
462
470
[widgets .RectangleSelector , widgets .EllipseSelector ])
463
471
def test_rectangle_rotate (ax , selector_class ):
472
+ ax .set_aspect (1 )
464
473
tool = selector_class (ax , onselect = noop , interactive = True )
465
474
# Draw rectangle
466
475
click_and_drag (tool , start = (100 , 100 ), end = (130 , 140 ))
@@ -474,19 +483,19 @@ def test_rectangle_rotate(ax, selector_class):
474
483
click_and_drag (tool , start = (130 , 140 ), end = (120 , 145 ))
475
484
do_event (tool , 'on_key_press' , key = 'r' )
476
485
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 )
479
488
assert_allclose (tool .rotation , 25.56 , atol = 0.01 )
480
489
tool .rotation = 45
481
490
assert tool .rotation == 45
482
491
# Corners should move
483
492
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 )
486
495
487
496
# Scale using top-right corner
488
497
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 )
490
499
491
500
if selector_class == widgets .RectangleSelector :
492
501
with pytest .raises (ValueError ):
@@ -508,36 +517,38 @@ def test_rectangle_add_remove_set(ax):
508
517
509
518
@pytest .mark .parametrize ('use_data_coordinates' , [False , True ])
510
519
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 ()
512
524
513
525
tool = widgets .RectangleSelector (ax , onselect = noop , interactive = True ,
514
526
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 ))
518
527
tool .add_state ('square' )
519
528
tool .add_state ('center' )
529
+ # Create rectangle, width 50 in data coordinates
530
+ click_and_drag (tool , start = (70 , 65 ), end = (120 , 75 ))
520
531
521
532
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 ))
531
534
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 ])
541
552
542
553
543
554
def test_ellipse (ax ):
@@ -1644,6 +1655,7 @@ def test_polygon_selector_verts_setter(fig_test, fig_ref, draw_bounding_box):
1644
1655
]
1645
1656
for (etype , event_args ) in event_sequence :
1646
1657
do_event (tool_ref , etype , ** event_args )
1658
+ np .testing .assert_allclose (tool_ref .verts , verts )
1647
1659
1648
1660
1649
1661
def test_polygon_selector_box (ax ):
@@ -1658,10 +1670,19 @@ def test_polygon_selector_box(ax):
1658
1670
* polygon_place_vertex (* verts [0 ]),
1659
1671
]
1660
1672
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
+
1661
1681
# Create selector
1662
1682
tool = widgets .PolygonSelector (ax , onselect = noop , draw_bounding_box = True )
1663
1683
for (etype , event_args ) in event_sequence :
1664
1684
do_event (tool , etype , ** event_args )
1685
+ np .testing .assert_allclose (tool .verts , verts , atol = atol )
1665
1686
1666
1687
# In order to trigger the correct callbacks, trigger events on the canvas
1667
1688
# instead of the individual tools
@@ -1676,7 +1697,7 @@ def test_polygon_selector_box(ax):
1676
1697
MouseEvent (
1677
1698
"button_release_event" , canvas , * t .transform ((20 , 20 )), 1 )._process ()
1678
1699
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 )
1680
1701
1681
1702
# Move using the center of the bounding box
1682
1703
MouseEvent (
@@ -1686,20 +1707,20 @@ def test_polygon_selector_box(ax):
1686
1707
MouseEvent (
1687
1708
"button_release_event" , canvas , * t .transform ((30 , 30 )), 1 )._process ()
1688
1709
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 )
1690
1711
1691
1712
# Remove a point from the polygon and check that the box extents update
1692
1713
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 )
1694
1715
1695
1716
MouseEvent (
1696
1717
"button_press_event" , canvas , * t .transform ((30 , 20 )), 3 )._process ()
1697
1718
MouseEvent (
1698
1719
"button_release_event" , canvas , * t .transform ((30 , 20 )), 3 )._process ()
1699
1720
np .testing .assert_allclose (
1700
- tool .verts , [(20 , 30 ), (30 , 40 ), (40 , 30 )])
1721
+ tool .verts , [(20 , 30 ), (30 , 40 ), (40 , 30 )], atol = atol )
1701
1722
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 )
1703
1724
1704
1725
1705
1726
def test_polygon_selector_clear_method (ax ):
0 commit comments