|
17 | 17 | AnchoredSizeBar,
|
18 | 18 | AnchoredDirectionArrows)
|
19 | 19 |
|
| 20 | +from matplotlib.backend_bases import MouseEvent |
20 | 21 | from matplotlib.colors import LogNorm
|
21 | 22 | from matplotlib.transforms import Bbox, TransformedBbox
|
22 | 23 | from itertools import product
|
| 24 | +import queue |
23 | 25 |
|
24 | 26 | import pytest
|
25 | 27 | import platform
|
26 | 28 |
|
27 | 29 | import numpy as np
|
28 | 30 | from numpy.testing import assert_array_equal, assert_array_almost_equal
|
29 | 31 |
|
| 32 | +import pytest |
| 33 | + |
30 | 34 |
|
31 | 35 | @image_comparison(baseline_images=['divider_append_axes'])
|
32 | 36 | def test_divider_append_axes():
|
@@ -422,3 +426,69 @@ def test_gettightbbox():
|
422 | 426 | bbox = fig.get_tightbbox(fig.canvas.get_renderer())
|
423 | 427 | np.testing.assert_array_almost_equal(bbox.extents,
|
424 | 428 | [-17.7, -13.9, 7.2, 5.4])
|
| 429 | + |
| 430 | + |
| 431 | +class TestPickingCallbacksOverlap(object): |
| 432 | + """Test pick events on normal, host or parasite axes.""" |
| 433 | + # Two rectangles are drawn and "clicked on", a small one and a big one |
| 434 | + # enclosing the small one. The axis on which they are drawn as well as the |
| 435 | + # rectangle that is clicked on are varied. |
| 436 | + # In each case we expect that both rectangles are picked if we click on the |
| 437 | + # small one and only the big one is picked if we click on the big one. |
| 438 | + # Also tests picking on normal axes ("gca") as a control. |
| 439 | + @pytest.fixture(autouse=True) |
| 440 | + def setup(self): |
| 441 | + self.q = queue.Queue() |
| 442 | + self.big = plt.Rectangle((0.25, 0.25), 0.5, 0.5, picker=5) |
| 443 | + self.small = plt.Rectangle((0.4, 0.4), 0.2, 0.2, facecolor="r", |
| 444 | + picker=5) |
| 445 | + plt.gcf().canvas.mpl_connect('pick_event', self.on_pick) |
| 446 | + |
| 447 | + def on_pick(self, event): |
| 448 | + self.q.put(event) |
| 449 | + |
| 450 | + @pytest.mark.parametrize("click_on", [ "big", "small" ]) |
| 451 | + @pytest.mark.parametrize("big_on_axes,small_on_axes", [ |
| 452 | + ("gca", "gca"), |
| 453 | + ("host", "host"), |
| 454 | + ("host", "parasite"), |
| 455 | + ("parasite", "host"), |
| 456 | + ("parasite", "parasite") |
| 457 | + ]) |
| 458 | + def test_picking_simple(self, big_on_axes, small_on_axes, click_on): |
| 459 | + # Shortcut |
| 460 | + rectangles_on_axes = (big_on_axes, small_on_axes) |
| 461 | + # Axes setup |
| 462 | + axes = { "gca": None, "host": None, "parasite": None } |
| 463 | + if "gca" in rectangles_on_axes: |
| 464 | + axes["gca"] = plt.gca() |
| 465 | + if "host" in rectangles_on_axes or "parasite" in rectangles_on_axes: |
| 466 | + axes["host"] = host_subplot(111) |
| 467 | + axes["parasite"] = axes["host"].twin() |
| 468 | + # Add rectangles to axes |
| 469 | + axes[big_on_axes].add_patch(self.big) |
| 470 | + axes[small_on_axes].add_patch(self.small) |
| 471 | + # Simulate picking with click mouse event |
| 472 | + if click_on == "big": |
| 473 | + click_axes = axes[big_on_axes] |
| 474 | + axes_coords = (0.3, 0.3) |
| 475 | + else: |
| 476 | + click_axes = axes[small_on_axes] |
| 477 | + axes_coords = (0.5, 0.5) |
| 478 | + # In reality mouse events never happen on parasite axes, only host axes |
| 479 | + if click_axes is axes["parasite"]: |
| 480 | + click_axes = axes["host"] |
| 481 | + (x, y) = click_axes.transAxes.transform(axes_coords) |
| 482 | + m = MouseEvent("button_press_event", click_axes.figure.canvas, x, y, |
| 483 | + button=1) |
| 484 | + click_axes.pick(m) |
| 485 | + # Wait at most a second for events; actual waiting only happens if sth. |
| 486 | + # is wrong and tests fail, so this won't slow down normal testing |
| 487 | + n_events = 2 if click_on == "small" else 1 |
| 488 | + event_rects = [] |
| 489 | + for i in range(n_events): |
| 490 | + event = self.q.get(True, 0.5) |
| 491 | + event_rects.append(event.artist) |
| 492 | + assert self.big in event_rects |
| 493 | + if click_on == "small": |
| 494 | + assert self.small in event_rects |
0 commit comments