1
+ import functools
2
+
1
3
from matplotlib ._api .deprecation import MatplotlibDeprecationWarning
2
4
import matplotlib .colors as mcolors
3
5
import matplotlib .widgets as widgets
@@ -1112,7 +1114,8 @@ def test_range_slider(orientation):
1112
1114
assert_allclose (slider .val , [0.1 , 0.34 ])
1113
1115
1114
1116
1115
- def check_polygon_selector (event_sequence , expected_result , selections_count ):
1117
+ def check_polygon_selector (event_sequence , expected_result , selections_count ,
1118
+ ** kwargs ):
1116
1119
"""
1117
1120
Helper function to test Polygon Selector.
1118
1121
@@ -1129,6 +1132,8 @@ def check_polygon_selector(event_sequence, expected_result, selections_count):
1129
1132
selections_count : int
1130
1133
Wait for the tool to call its `onselect` function `selections_count`
1131
1134
times, before comparing the result to the `expected_result`
1135
+ **kwargs
1136
+ Keyword arguments are passed to PolygonSelector.
1132
1137
"""
1133
1138
ax = get_ax ()
1134
1139
@@ -1138,7 +1143,7 @@ def onselect(vertices):
1138
1143
ax ._selections_count += 1
1139
1144
ax ._current_result = vertices
1140
1145
1141
- tool = widgets .PolygonSelector (ax , onselect )
1146
+ tool = widgets .PolygonSelector (ax , onselect , ** kwargs )
1142
1147
1143
1148
for (etype , event_args ) in event_sequence :
1144
1149
do_event (tool , etype , ** event_args )
@@ -1159,14 +1164,18 @@ def polygon_remove_vertex(xdata, ydata):
1159
1164
('release' , dict (xdata = xdata , ydata = ydata , button = 3 ))]
1160
1165
1161
1166
1162
- def test_polygon_selector ():
1167
+ @pytest .mark .parametrize ('draw_bounding_box' , [False , True ])
1168
+ def test_polygon_selector (draw_bounding_box ):
1169
+ check_selector = functools .partial (
1170
+ check_polygon_selector , draw_bounding_box = draw_bounding_box )
1171
+
1163
1172
# Simple polygon
1164
1173
expected_result = [(50 , 50 ), (150 , 50 ), (50 , 150 )]
1165
1174
event_sequence = (polygon_place_vertex (50 , 50 )
1166
1175
+ polygon_place_vertex (150 , 50 )
1167
1176
+ polygon_place_vertex (50 , 150 )
1168
1177
+ polygon_place_vertex (50 , 50 ))
1169
- check_polygon_selector (event_sequence , expected_result , 1 )
1178
+ check_selector (event_sequence , expected_result , 1 )
1170
1179
1171
1180
# Move first vertex before completing the polygon.
1172
1181
expected_result = [(75 , 50 ), (150 , 50 ), (50 , 150 )]
@@ -1180,7 +1189,7 @@ def test_polygon_selector():
1180
1189
('on_key_release' , dict (key = 'control' ))]
1181
1190
+ polygon_place_vertex (50 , 150 )
1182
1191
+ polygon_place_vertex (75 , 50 ))
1183
- check_polygon_selector (event_sequence , expected_result , 1 )
1192
+ check_selector (event_sequence , expected_result , 1 )
1184
1193
1185
1194
# Move first two vertices at once before completing the polygon.
1186
1195
expected_result = [(50 , 75 ), (150 , 75 ), (50 , 150 )]
@@ -1194,7 +1203,7 @@ def test_polygon_selector():
1194
1203
('on_key_release' , dict (key = 'shift' ))]
1195
1204
+ polygon_place_vertex (50 , 150 )
1196
1205
+ polygon_place_vertex (50 , 75 ))
1197
- check_polygon_selector (event_sequence , expected_result , 1 )
1206
+ check_selector (event_sequence , expected_result , 1 )
1198
1207
1199
1208
# Move first vertex after completing the polygon.
1200
1209
expected_result = [(75 , 50 ), (150 , 50 ), (50 , 150 )]
@@ -1206,7 +1215,7 @@ def test_polygon_selector():
1206
1215
('press' , dict (xdata = 50 , ydata = 50 )),
1207
1216
('onmove' , dict (xdata = 75 , ydata = 50 )),
1208
1217
('release' , dict (xdata = 75 , ydata = 50 ))])
1209
- check_polygon_selector (event_sequence , expected_result , 2 )
1218
+ check_selector (event_sequence , expected_result , 2 )
1210
1219
1211
1220
# Move all vertices after completing the polygon.
1212
1221
expected_result = [(75 , 75 ), (175 , 75 ), (75 , 175 )]
@@ -1220,7 +1229,7 @@ def test_polygon_selector():
1220
1229
('onmove' , dict (xdata = 125 , ydata = 125 )),
1221
1230
('release' , dict (xdata = 125 , ydata = 125 )),
1222
1231
('on_key_release' , dict (key = 'shift' ))])
1223
- check_polygon_selector (event_sequence , expected_result , 2 )
1232
+ check_selector (event_sequence , expected_result , 2 )
1224
1233
1225
1234
# Try to move a vertex and move all before placing any vertices.
1226
1235
expected_result = [(50 , 50 ), (150 , 50 ), (50 , 150 )]
@@ -1240,7 +1249,7 @@ def test_polygon_selector():
1240
1249
+ polygon_place_vertex (150 , 50 )
1241
1250
+ polygon_place_vertex (50 , 150 )
1242
1251
+ polygon_place_vertex (50 , 50 ))
1243
- check_polygon_selector (event_sequence , expected_result , 1 )
1252
+ check_selector (event_sequence , expected_result , 1 )
1244
1253
1245
1254
# Try to place vertex out-of-bounds, then reset, and start a new polygon.
1246
1255
expected_result = [(50 , 50 ), (150 , 50 ), (50 , 150 )]
@@ -1252,10 +1261,11 @@ def test_polygon_selector():
1252
1261
+ polygon_place_vertex (150 , 50 )
1253
1262
+ polygon_place_vertex (50 , 150 )
1254
1263
+ polygon_place_vertex (50 , 50 ))
1255
- check_polygon_selector (event_sequence , expected_result , 1 )
1264
+ check_selector (event_sequence , expected_result , 1 )
1256
1265
1257
1266
1258
- def test_polygon_selector_set_props_handle_props ():
1267
+ @pytest .mark .parametrize ('draw_bounding_box' , [False , True ])
1268
+ def test_polygon_selector_set_props_handle_props (draw_bounding_box ):
1259
1269
ax = get_ax ()
1260
1270
1261
1271
ax ._selections_count = 0
@@ -1266,7 +1276,8 @@ def onselect(vertices):
1266
1276
1267
1277
tool = widgets .PolygonSelector (ax , onselect ,
1268
1278
props = dict (color = 'b' , alpha = 0.2 ),
1269
- handle_props = dict (alpha = 0.5 ))
1279
+ handle_props = dict (alpha = 0.5 ),
1280
+ draw_bounding_box = draw_bounding_box )
1270
1281
1271
1282
event_sequence = (polygon_place_vertex (50 , 50 )
1272
1283
+ polygon_place_vertex (150 , 50 )
@@ -1308,7 +1319,8 @@ def onselect(verts):
1308
1319
1309
1320
# Change the order that the extra point is inserted in
1310
1321
@pytest .mark .parametrize ('idx' , [1 , 2 , 3 ])
1311
- def test_polygon_selector_remove (idx ):
1322
+ @pytest .mark .parametrize ('draw_bounding_box' , [False , True ])
1323
+ def test_polygon_selector_remove (idx , draw_bounding_box ):
1312
1324
verts = [(50 , 50 ), (150 , 50 ), (50 , 150 )]
1313
1325
event_sequence = [polygon_place_vertex (* verts [0 ]),
1314
1326
polygon_place_vertex (* verts [1 ]),
@@ -1321,20 +1333,24 @@ def test_polygon_selector_remove(idx):
1321
1333
event_sequence .append (polygon_remove_vertex (200 , 200 ))
1322
1334
# Flatten list of lists
1323
1335
event_sequence = sum (event_sequence , [])
1324
- check_polygon_selector (event_sequence , verts , 2 )
1336
+ check_polygon_selector (event_sequence , verts , 2 ,
1337
+ draw_bounding_box = draw_bounding_box )
1325
1338
1326
1339
1327
- def test_polygon_selector_remove_first_point ():
1340
+ @pytest .mark .parametrize ('draw_bounding_box' , [False , True ])
1341
+ def test_polygon_selector_remove_first_point (draw_bounding_box ):
1328
1342
verts = [(50 , 50 ), (150 , 50 ), (50 , 150 )]
1329
1343
event_sequence = (polygon_place_vertex (* verts [0 ]) +
1330
1344
polygon_place_vertex (* verts [1 ]) +
1331
1345
polygon_place_vertex (* verts [2 ]) +
1332
1346
polygon_place_vertex (* verts [0 ]) +
1333
1347
polygon_remove_vertex (* verts [0 ]))
1334
- check_polygon_selector (event_sequence , verts [1 :], 2 )
1348
+ check_polygon_selector (event_sequence , verts [1 :], 2 ,
1349
+ draw_bounding_box = draw_bounding_box )
1335
1350
1336
1351
1337
- def test_polygon_selector_redraw ():
1352
+ @pytest .mark .parametrize ('draw_bounding_box' , [False , True ])
1353
+ def test_polygon_selector_redraw (draw_bounding_box ):
1338
1354
verts = [(50 , 50 ), (150 , 50 ), (50 , 150 )]
1339
1355
event_sequence = (polygon_place_vertex (* verts [0 ]) +
1340
1356
polygon_place_vertex (* verts [1 ]) +
@@ -1352,7 +1368,8 @@ def test_polygon_selector_redraw():
1352
1368
def onselect (vertices ):
1353
1369
pass
1354
1370
1355
- tool = widgets .PolygonSelector (ax , onselect )
1371
+ tool = widgets .PolygonSelector (ax , onselect ,
1372
+ draw_bounding_box = draw_bounding_box )
1356
1373
for (etype , event_args ) in event_sequence :
1357
1374
do_event (tool , etype , ** event_args )
1358
1375
# After removing two verts, only one remains, and the
@@ -1382,6 +1399,56 @@ def onselect(vertices):
1382
1399
do_event (tool_ref , etype , ** event_args )
1383
1400
1384
1401
1402
+ def test_polygon_selector_box ():
1403
+ # Create a diamond shape
1404
+ verts = [(20 , 0 ), (0 , 20 ), (20 , 40 ), (40 , 20 )]
1405
+ event_sequence = (polygon_place_vertex (* verts [0 ]) +
1406
+ polygon_place_vertex (* verts [1 ]) +
1407
+ polygon_place_vertex (* verts [2 ]) +
1408
+ polygon_place_vertex (* verts [3 ]) +
1409
+ polygon_place_vertex (* verts [0 ]))
1410
+
1411
+ ax = get_ax ()
1412
+
1413
+ def onselect (vertices ):
1414
+ pass
1415
+
1416
+ # Create selector
1417
+ tool = widgets .PolygonSelector (ax , onselect , draw_bounding_box = True )
1418
+ for (etype , event_args ) in event_sequence :
1419
+ do_event (tool , etype , ** event_args )
1420
+
1421
+ # In order to trigger the correct callbacks, trigger events on the canvas
1422
+ # instead of the individual tools
1423
+ t = ax .transData
1424
+ canvas = ax .figure .canvas
1425
+
1426
+ # Scale to half size using the top right corner of the bounding box
1427
+ canvas .button_press_event (* t .transform ((40 , 40 )), 1 )
1428
+ canvas .motion_notify_event (* t .transform ((20 , 20 )))
1429
+ canvas .button_release_event (* t .transform ((20 , 20 )), 1 )
1430
+ np .testing .assert_allclose (
1431
+ tool .verts , [(10 , 0 ), (0 , 10 ), (10 , 20 ), (20 , 10 )])
1432
+
1433
+ # Move using the center of the bounding box
1434
+ canvas .button_press_event (* t .transform ((10 , 10 )), 1 )
1435
+ canvas .motion_notify_event (* t .transform ((30 , 30 )))
1436
+ canvas .button_release_event (* t .transform ((30 , 30 )), 1 )
1437
+ np .testing .assert_allclose (
1438
+ tool .verts , [(30 , 20 ), (20 , 30 ), (30 , 40 ), (40 , 30 )])
1439
+
1440
+ # Remove a point from the polygon and check that the box extents update
1441
+ np .testing .assert_allclose (
1442
+ tool ._box .extents , (20.0 , 40.0 , 20.0 , 40.0 ))
1443
+
1444
+ canvas .button_press_event (* t .transform ((30 , 20 )), 3 )
1445
+ canvas .button_release_event (* t .transform ((30 , 20 )), 3 )
1446
+ np .testing .assert_allclose (
1447
+ tool .verts , [(20 , 30 ), (30 , 40 ), (40 , 30 )])
1448
+ np .testing .assert_allclose (
1449
+ tool ._box .extents , (20.0 , 40.0 , 30.0 , 40.0 ))
1450
+
1451
+
1385
1452
@pytest .mark .parametrize (
1386
1453
"horizOn, vertOn" ,
1387
1454
[(True , True ), (True , False ), (False , True )],
0 commit comments