@@ -83,19 +83,20 @@ def test_rectangle_selector(ax, kwargs):
8383
8484 # purposely drag outside of axis for release
8585 do_event (tool , 'release' , xdata = 250 , ydata = 250 , button = 1 )
86+ do_event (tool , 'onmove' , xdata = 250 , ydata = 250 , button = 1 )
8687
8788 if kwargs .get ('drawtype' , None ) not in ['line' , 'none' ]:
8889 assert_allclose (tool .geometry ,
89- [[100. , 100 , 199 , 199 , 100 ],
90+ [[100 , 100 , 199 , 199 , 100 ],
9091 [100 , 199 , 199 , 100 , 100 ]],
9192 err_msg = tool .geometry )
9293
9394 onselect .assert_called_once ()
9495 (epress , erelease ), kwargs = onselect .call_args
9596 assert epress .xdata == 100
9697 assert epress .ydata == 100
97- assert erelease .xdata == 199
98- assert erelease .ydata == 199
98+ assert erelease .xdata == 200
99+ assert erelease .ydata == 200
99100 assert kwargs == {}
100101
101102
@@ -192,10 +193,16 @@ def test_rectangle_selector_set_props_handle_props(ax):
192193 assert artist .get_alpha () == 0.3
193194
194195
195- 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 ):
196203 tool = widgets .RectangleSelector (ax , interactive = True )
197204 # Create rectangle
198- click_and_drag (tool , start = ( 0 , 10 ), end = ( 100 , 120 ) )
205+ click_and_drag (tool , start = start , end = end )
199206 assert_allclose (tool .extents , (0.0 , 100.0 , 10.0 , 120.0 ))
200207
201208 # resize NE handle
@@ -316,16 +323,16 @@ def test_rectangle_resize_center(ax, add_state):
316323 xdata_new , ydata_new = xdata + xdiff , ydata + ydiff
317324 click_and_drag (tool , start = (xdata , ydata ), end = (xdata_new , ydata_new ),
318325 key = use_key )
319- assert tool .extents == (xdata_new , extents [1 ] - xdiff ,
320- ydata_new , extents [3 ] - ydiff )
326+ assert_allclose ( tool .extents , (xdata_new , extents [1 ] - xdiff ,
327+ ydata_new , extents [3 ] - ydiff ) )
321328
322329
323330@pytest .mark .parametrize ('add_state' , [True , False ])
324331def test_rectangle_resize_square (ax , add_state ):
325332 tool = widgets .RectangleSelector (ax , interactive = True )
326333 # Create rectangle
327334 click_and_drag (tool , start = (70 , 65 ), end = (120 , 115 ))
328- assert tool .extents == (70.0 , 120.0 , 65.0 , 115.0 )
335+ assert_allclose ( tool .extents , (70.0 , 120.0 , 65.0 , 115.0 ) )
329336
330337 if add_state :
331338 tool .add_state ('square' )
@@ -340,8 +347,8 @@ def test_rectangle_resize_square(ax, add_state):
340347 xdata_new , ydata_new = xdata + xdiff , ydata + ydiff
341348 click_and_drag (tool , start = (xdata , ydata ), end = (xdata_new , ydata_new ),
342349 key = use_key )
343- assert tool .extents == (extents [0 ], xdata_new ,
344- extents [2 ], extents [3 ] + xdiff )
350+ assert_allclose ( tool .extents , (extents [0 ], xdata_new ,
351+ extents [2 ], extents [3 ] + xdiff ) )
345352
346353 # resize E handle
347354 extents = tool .extents
@@ -390,11 +397,12 @@ def test_rectangle_resize_square(ax, add_state):
390397 xdata_new , ydata_new = xdata + xdiff , ydata + ydiff
391398 click_and_drag (tool , start = (xdata , ydata ), end = (xdata_new , ydata_new ),
392399 key = use_key )
393- assert_allclose (tool .extents , (extents [ 0 ] + ydiff , extents [1 ],
394- ydata_new , extents [3 ]))
400+ assert_allclose (tool .extents , (xdata_new , extents [1 ],
401+ extents [ 2 ] + xdiff , extents [3 ]))
395402
396403
397404def test_rectangle_resize_square_center (ax ):
405+ ax .set_aspect (1 )
398406 tool = widgets .RectangleSelector (ax , interactive = True )
399407 # Create rectangle
400408 click_and_drag (tool , start = (70 , 65 ), end = (120 , 115 ))
@@ -460,6 +468,7 @@ def test_rectangle_resize_square_center(ax):
460468@pytest .mark .parametrize ('selector_class' ,
461469 [widgets .RectangleSelector , widgets .EllipseSelector ])
462470def test_rectangle_rotate (ax , selector_class ):
471+ ax .set_aspect (1 )
463472 tool = selector_class (ax , interactive = True )
464473 # Draw rectangle
465474 click_and_drag (tool , start = (100 , 100 ), end = (130 , 140 ))
@@ -473,19 +482,19 @@ def test_rectangle_rotate(ax, selector_class):
473482 click_and_drag (tool , start = (130 , 140 ), end = (120 , 145 ))
474483 do_event (tool , 'on_key_press' , key = 'r' )
475484 assert len (tool ._state ) == 0
476- # Extents shouldn't change ( as shape of rectangle hasn't changed)
477- 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 )
478487 assert_allclose (tool .rotation , 25.56 , atol = 0.01 )
479488 tool .rotation = 45
480489 assert tool .rotation == 45
481490 # Corners should move
482491 assert_allclose (tool .corners ,
483- np .array ([[118.53 , 139.75 , 111.46 , 90.25 ],
484- [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 )
485494
486495 # Scale using top-right corner
487496 click_and_drag (tool , start = (110 , 145 ), end = (110 , 160 ))
488- 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 )
489498
490499 if selector_class == widgets .RectangleSelector :
491500 with pytest .raises (ValueError ):
@@ -507,36 +516,38 @@ def test_rectangle_add_remove_set(ax):
507516
508517@pytest .mark .parametrize ('use_data_coordinates' , [False , True ])
509518def test_rectangle_resize_square_center_aspect (ax , use_data_coordinates ):
510- 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 ()
511523
512524 tool = widgets .RectangleSelector (ax , interactive = True ,
513525 use_data_coordinates = use_data_coordinates )
514- # Create rectangle
515- click_and_drag (tool , start = (70 , 65 ), end = (120 , 115 ))
516- assert_allclose (tool .extents , (70.0 , 120.0 , 65.0 , 115.0 ))
517526 tool .add_state ('square' )
518527 tool .add_state ('center' )
528+ # Create rectangle, width 50 in data coordinates
529+ click_and_drag (tool , start = (70 , 65 ), end = (120 , 75 ))
519530
520531 if use_data_coordinates :
521- # resize E handle
522- extents = tool .extents
523- xdata , ydata , width = extents [1 ], extents [3 ], extents [1 ] - extents [0 ]
524- xdiff , ycenter = 10 , extents [2 ] + (extents [3 ] - extents [2 ]) / 2
525- xdata_new , ydata_new = xdata + xdiff , ydata
526- ychange = width / 2 + xdiff
527- click_and_drag (tool , start = (xdata , ydata ), end = (xdata_new , ydata_new ))
528- assert_allclose (tool .extents , [extents [0 ] - xdiff , xdata_new ,
529- ycenter - ychange , ycenter + ychange ])
532+ assert_allclose (tool .extents , (20 , 120 , 15 , 115 ))
530533 else :
531- # resize E handle
532- extents = tool .extents
533- xdata , ydata = extents [1 ], extents [3 ]
534- xdiff = 10
535- xdata_new , ydata_new = xdata + xdiff , ydata
536- ychange = xdiff * 1 / tool ._aspect_ratio_correction
537- click_and_drag (tool , start = (xdata , ydata ), end = (xdata_new , ydata_new ))
538- assert_allclose (tool .extents , [extents [0 ] - xdiff , xdata_new ,
539- 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 ])
540551
541552
542553def test_ellipse (ax ):
@@ -1642,6 +1653,7 @@ def test_polygon_selector_verts_setter(fig_test, fig_ref, draw_bounding_box):
16421653 ]
16431654 for (etype , event_args ) in event_sequence :
16441655 do_event (tool_ref , etype , ** event_args )
1656+ np .testing .assert_allclose (tool_ref .verts , verts )
16451657
16461658
16471659def test_polygon_selector_box (ax ):
@@ -1656,10 +1668,19 @@ def test_polygon_selector_box(ax):
16561668 * polygon_place_vertex (* verts [0 ]),
16571669 ]
16581670
1671+ # Set smaller axes limits to reduce errors in converting from data to
1672+ # display coords. The canvas size is 640 x 640, so we need a tolerance of
1673+ # (data width / canvas width) = 50 / 640 ~ 0.08 when comparing points in
1674+ # data space
1675+ ax .set_xlim (- 5 , 45 )
1676+ ax .set_ylim (- 5 , 45 )
1677+ atol = 0.08
1678+
16591679 # Create selector
16601680 tool = widgets .PolygonSelector (ax , draw_bounding_box = True )
16611681 for (etype , event_args ) in event_sequence :
16621682 do_event (tool , etype , ** event_args )
1683+ np .testing .assert_allclose (tool .verts , verts , atol = atol )
16631684
16641685 # In order to trigger the correct callbacks, trigger events on the canvas
16651686 # instead of the individual tools
@@ -1674,7 +1695,7 @@ def test_polygon_selector_box(ax):
16741695 MouseEvent (
16751696 "button_release_event" , canvas , * t .transform ((20 , 20 )), 1 )._process ()
16761697 np .testing .assert_allclose (
1677- tool .verts , [(10 , 0 ), (0 , 10 ), (10 , 20 ), (20 , 10 )])
1698+ tool .verts , [(10 , 0 ), (0 , 10 ), (10 , 20 ), (20 , 10 )], atol = atol )
16781699
16791700 # Move using the center of the bounding box
16801701 MouseEvent (
@@ -1684,20 +1705,20 @@ def test_polygon_selector_box(ax):
16841705 MouseEvent (
16851706 "button_release_event" , canvas , * t .transform ((30 , 30 )), 1 )._process ()
16861707 np .testing .assert_allclose (
1687- tool .verts , [(30 , 20 ), (20 , 30 ), (30 , 40 ), (40 , 30 )])
1708+ tool .verts , [(30 , 20 ), (20 , 30 ), (30 , 40 ), (40 , 30 )], atol = atol )
16881709
16891710 # Remove a point from the polygon and check that the box extents update
16901711 np .testing .assert_allclose (
1691- tool ._box .extents , (20.0 , 40.0 , 20.0 , 40.0 ))
1712+ tool ._box .extents , (20.0 , 40.0 , 20.0 , 40.0 ), atol = atol )
16921713
16931714 MouseEvent (
16941715 "button_press_event" , canvas , * t .transform ((30 , 20 )), 3 )._process ()
16951716 MouseEvent (
16961717 "button_release_event" , canvas , * t .transform ((30 , 20 )), 3 )._process ()
16971718 np .testing .assert_allclose (
1698- tool .verts , [(20 , 30 ), (30 , 40 ), (40 , 30 )])
1719+ tool .verts , [(20 , 30 ), (30 , 40 ), (40 , 30 )], atol = atol )
16991720 np .testing .assert_allclose (
1700- tool ._box .extents , (20.0 , 40.0 , 30.0 , 40.0 ))
1721+ tool ._box .extents , (20.0 , 40.0 , 30.0 , 40.0 ), atol = atol )
17011722
17021723
17031724def test_polygon_selector_clear_method (ax ):
0 commit comments