|
1 | 1 | from collections import namedtuple
|
2 | 2 |
|
| 3 | +import numpy as np |
3 | 4 | from numpy.testing import assert_allclose
|
4 | 5 | import pytest
|
5 | 6 |
|
6 | 7 | from matplotlib.testing.decorators import image_comparison
|
7 | 8 | import matplotlib.pyplot as plt
|
8 | 9 | import matplotlib.patches as mpatches
|
9 | 10 | import matplotlib.lines as mlines
|
| 11 | +from matplotlib.backend_bases import MouseButton |
| 12 | + |
10 | 13 | from matplotlib.offsetbox import (
|
11 |
| - AnchoredOffsetbox, DrawingArea, _get_packed_offsets) |
| 14 | + AnchoredOffsetbox, AnnotationBbox, DrawingArea, OffsetImage, TextArea, |
| 15 | + _get_packed_offsets) |
12 | 16 |
|
13 | 17 |
|
14 | 18 | @image_comparison(['offsetbox_clipping'], remove_text=True)
|
@@ -182,3 +186,55 @@ def test_get_packed_offsets_equal(wd_list, total, sep, expected):
|
182 | 186 | def test_get_packed_offsets_equal_total_none_sep_none():
|
183 | 187 | with pytest.raises(ValueError):
|
184 | 188 | _get_packed_offsets([(1, 0)] * 3, total=None, sep=None, mode='equal')
|
| 189 | + |
| 190 | + |
| 191 | +@pytest.mark.parametrize('child_type', ['draw', 'image', 'text']) |
| 192 | +@pytest.mark.parametrize('boxcoords', |
| 193 | + ['axes fraction', 'axes pixels', 'axes points', |
| 194 | + 'data']) |
| 195 | +def test_picking(child_type, boxcoords): |
| 196 | + # These all take up approximately the same area. |
| 197 | + if child_type == 'draw': |
| 198 | + picking_child = DrawingArea(5, 5) |
| 199 | + picking_child.add_artist(mpatches.Rectangle((0, 0), 5, 5, linewidth=0)) |
| 200 | + elif child_type == 'image': |
| 201 | + im = np.ones((5, 5)) |
| 202 | + im[2, 2] = 0 |
| 203 | + picking_child = OffsetImage(im) |
| 204 | + elif child_type == 'text': |
| 205 | + picking_child = TextArea('\N{Black Square}', textprops={'fontsize': 5}) |
| 206 | + else: |
| 207 | + assert False, f'Unknown picking child type {child_type}' |
| 208 | + |
| 209 | + fig, ax = plt.subplots() |
| 210 | + ab = AnnotationBbox(picking_child, (0.5, 0.5), boxcoords=boxcoords) |
| 211 | + ab.set_picker(True) |
| 212 | + ax.add_artist(ab) |
| 213 | + |
| 214 | + calls = [] |
| 215 | + fig.canvas.mpl_connect('pick_event', lambda event: calls.append(event)) |
| 216 | + |
| 217 | + # Annotation should be picked by an event occurring at its center. |
| 218 | + if boxcoords == 'axes points': |
| 219 | + x, y = ax.transAxes.transform_point((0, 0)) |
| 220 | + x += 0.5 * fig.dpi / 72 |
| 221 | + y += 0.5 * fig.dpi / 72 |
| 222 | + elif boxcoords == 'axes pixels': |
| 223 | + x, y = ax.transAxes.transform_point((0, 0)) |
| 224 | + x += 0.5 |
| 225 | + y += 0.5 |
| 226 | + else: |
| 227 | + x, y = ax.transAxes.transform_point((0.5, 0.5)) |
| 228 | + fig.canvas.draw() |
| 229 | + calls.clear() |
| 230 | + fig.canvas.button_press_event(x, y, MouseButton.LEFT) |
| 231 | + assert len(calls) == 1 and calls[0].artist == ab |
| 232 | + |
| 233 | + # Annotation should *not* be picked by an event at its original center |
| 234 | + # point when the limits have changed enough to hide the *xy* point. |
| 235 | + ax.set_xlim(-1, 0) |
| 236 | + ax.set_ylim(-1, 0) |
| 237 | + fig.canvas.draw() |
| 238 | + calls.clear() |
| 239 | + fig.canvas.button_press_event(x, y, MouseButton.LEFT) |
| 240 | + assert len(calls) == 0 |
0 commit comments