Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fix AnnotationBbox picking and a bit of cleanup #17002

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 6 additions & 20 deletions lib/matplotlib/offsetbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -1360,24 +1360,6 @@ def set_zoom(self, zoom):
def get_zoom(self):
return self._zoom

# def set_axes(self, axes):
# self.image.set_axes(axes)
# martist.Artist.set_axes(self, axes)

# def set_offset(self, xy):
# """
# Set the offset of the container.
#
# Parameters
# ----------
# xy : (float, float)
# The (x, y) coordinates of the offset in display units.
# """
# self._offset = xy

# self.offset_transform.clear()
# self.offset_transform.translate(xy[0], xy[1])

def get_offset(self):
"""Return offset of the container."""
return self._offset
Expand Down Expand Up @@ -1448,7 +1430,7 @@ def __init__(self, offsetbox, xy,

xybox : (float, float), default: *xy*
The position *(x, y)* to place the text at. The coordinate system
is determined by *textcoords*.
is determined by *boxcoords*.

xycoords : str or `.Artist` or `.Transform` or callable or \
(float, float), default: 'data'
Expand Down Expand Up @@ -1541,6 +1523,11 @@ def contains(self, mouseevent):
inside, info = self._default_contains(mouseevent)
if inside is not None:
return inside, info

xy_pixel = self._get_position_xy(None)
if not self._check_xy(None, xy_pixel):
return False, {}

t, tinfo = self.offsetbox.contains(mouseevent)
#if self.arrow_patch is not None:
# a, ainfo=self.arrow_patch.contains(event)
Expand Down Expand Up @@ -1659,7 +1646,6 @@ def draw(self, renderer):
return

xy_pixel = self._get_position_xy(renderer)

if not self._check_xy(renderer, xy_pixel):
return

Expand Down
58 changes: 57 additions & 1 deletion lib/matplotlib/tests/test_offsetbox.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
from collections import namedtuple

import numpy as np
from numpy.testing import assert_allclose
import pytest

from matplotlib.testing.decorators import image_comparison
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import matplotlib.lines as mlines
from matplotlib.backend_bases import MouseButton

from matplotlib.offsetbox import (
AnchoredOffsetbox, DrawingArea, _get_packed_offsets)
AnchoredOffsetbox, AnnotationBbox, DrawingArea, OffsetImage, TextArea,
_get_packed_offsets)


@image_comparison(['offsetbox_clipping'], remove_text=True)
Expand Down Expand Up @@ -182,3 +186,55 @@ def test_get_packed_offsets_equal(wd_list, total, sep, expected):
def test_get_packed_offsets_equal_total_none_sep_none():
with pytest.raises(ValueError):
_get_packed_offsets([(1, 0)] * 3, total=None, sep=None, mode='equal')


@pytest.mark.parametrize('child_type', ['draw', 'image', 'text'])
@pytest.mark.parametrize('boxcoords',
['axes fraction', 'axes pixels', 'axes points',
'data'])
def test_picking(child_type, boxcoords):
# These all take up approximately the same area.
if child_type == 'draw':
picking_child = DrawingArea(5, 5)
picking_child.add_artist(mpatches.Rectangle((0, 0), 5, 5, linewidth=0))
elif child_type == 'image':
im = np.ones((5, 5))
im[2, 2] = 0
picking_child = OffsetImage(im)
elif child_type == 'text':
picking_child = TextArea('\N{Black Square}', textprops={'fontsize': 5})
else:
assert False, f'Unknown picking child type {child_type}'

fig, ax = plt.subplots()
ab = AnnotationBbox(picking_child, (0.5, 0.5), boxcoords=boxcoords)
ab.set_picker(True)
ax.add_artist(ab)

calls = []
fig.canvas.mpl_connect('pick_event', lambda event: calls.append(event))

# Annotation should be picked by an event occurring at its center.
if boxcoords == 'axes points':
x, y = ax.transAxes.transform_point((0, 0))
x += 0.5 * fig.dpi / 72
y += 0.5 * fig.dpi / 72
elif boxcoords == 'axes pixels':
x, y = ax.transAxes.transform_point((0, 0))
x += 0.5
y += 0.5
else:
x, y = ax.transAxes.transform_point((0.5, 0.5))
fig.canvas.draw()
calls.clear()
fig.canvas.button_press_event(x, y, MouseButton.LEFT)
assert len(calls) == 1 and calls[0].artist == ab

# Annotation should *not* be picked by an event at its original center
# point when the limits have changed enough to hide the *xy* point.
ax.set_xlim(-1, 0)
ax.set_ylim(-1, 0)
fig.canvas.draw()
calls.clear()
fig.canvas.button_press_event(x, y, MouseButton.LEFT)
assert len(calls) == 0