8000 Deprecate setting a Collection/Patch's pickradius via set_picker. by anntzer · Pull Request #19026 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Deprecate setting a Collection/Patch's pickradius via set_picker. #19026

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

Closed
wants to merge 1 commit into from
Closed
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
5 changes: 5 additions & 0 deletions doc/api/next_api_changes/deprecations/19026-AL.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Setting pickradius on Collections and Patches via ``set_picker``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Setting the pickradius (i.e. the tolerance for pick events and containment
checks)of a `.Collection` or a `.Patch` via `.Artist.set_picker` is deprecated;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
checks)of a `.Collection` or a `.Patch` via `.Artist.set_picker` is deprecated;
checks) of a `.Collection` or a `.Patch` via `.Artist.set_picker` is deprecated;

use ``set_pickradius`` instead.
8 changes: 4 additions & 4 deletions lib/matplotlib/artist.py
8000
Original file line number Diff line number Diff line change
Expand Up @@ -558,10 +558,10 @@ def set_picker(self, picker):
artist, return *hit=True* and props is a dictionary of
properties you want added to the PickEvent attributes.

- *deprecated*: For `.Line2D` only, *picker* can also be a float
that sets the tolerance for checking whether an event occurred
"on" the line; this is deprecated. Use `.Line2D.set_pickradius`
instead.
- *deprecated*: For `.Line2D` and `.Collection`, *picker* can also
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- *deprecated*: For `.Line2D` and `.Collection`, *picker* can also
- *deprecated*: For `.Line2D`, `.Patch` and `.Collection`, *picker* can also

be a float that sets the tolerance for checking whether an event
occurred "on" the artist; this is deprecated. Use
`.Line2D.set_pickradius`/`.Collection.set_pickradius` instead.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`.Line2D.set_pickradius`/`.Collection.set_pickradius` instead.
`.Line2D.set_pickradius`/`.Collection.set_pickradius`/`.Patch.set_pickradius`
instead.

"""
self._picker = picker

Expand Down
26 changes: 13 additions & 13 deletions lib/matplotlib/collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,17 @@ def draw(self, renderer):
renderer.close_group(self.__class__.__name__)
self.stale = False

def set_picker(self, p):
# docstring inherited
# After deprecation, the whole method can be deleted and inherited.
if isinstance(p, Number) and not isinstance(p, bool):
cbook.warn_deprecated(
"3.4", message="Setting the collections's pick radius via "
"set_picker is deprecated since %(since)s and will be removed "
"%(removal)s; use set_pickradius instead.")
self.set_pickradius(p)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should you then set p to True since you've removed the type checks later?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and probably make the same change in lines.py as well?

self._picker = p

def set_pickradius(self, pr):
"""
Set the pick radius used for containment tests.
Expand All @@ -439,32 +450,21 @@ def contains(self, mouseevent):
inside, info = self._default_contains(mouseevent)
if inside is not None:
return inside, info

if not self.get_visible():
return False, {}

pickradius = (
float(self._picker)
if isinstance(self._picker, Number) and
self._picker is not True # the bool, not just nonzero or 1
else self._pickradius)

if self.axes:
self.axes._unstale_viewLim()

transform, transOffset, offsets, paths = self._prepare_points()

# Tests if the point is contained on one of the polygons formed
# by the control points of each of the paths. A point is considered
# "on" a path if it would lie within a stroke of width 2*pickradius
# following the path. If pickradius <= 0, then we instead simply check
# if the point is *inside* of the path instead.
ind = _path.point_in_path_collection(
mouseevent.x, mouseevent.y, pickradius,
mouseevent.x, mouseevent.y, self._pickradius,
transform.frozen(), paths, self.get_transforms(),
offsets, transOffset, pickradius <= 0,
offsets, transOffset, self._pickradius <= 0,
self._offset_position)

return len(ind) > 0, dict(ind=ind)

def set_urls(self, urls):
Expand Down
60 changes: 47 additions & 13 deletions lib/matplotlib/patches.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ def __init__(self,
# unscaled dashes. Needed to scale dash patterns by lw
self._us_dashes = None
self._linewidth = 0
self._pickradius = None

self.set_fill(fill)
self.set_linestyle(linestyle)
Expand All @@ -102,9 +103,7 @@ def __init__(self,
self.set_hatch(hatch)
self.set_capstyle(capstyle)
self.set_joinstyle(joinstyle)

if len(kwargs):
self.update(kwargs)
self.update(kwargs)

def get_verts(self):
"""
Expand All @@ -120,17 +119,52 @@ def get_verts(self):
return polygons[0]
return []

def set_picker(self, p):
# docstring inherited
# After deprecation, the whole method can be deleted and inherited.
if isinstance(p, Number) and not isinstance(p, bool):
cbook.warn_deprecated(
"3.4", message="Setting the collections's pick radius via "
"set_picker is deprecated since %(since)s and will be removed "
"%(removal)s; use set_pickradius instead.")
self.set_pickradius(p)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

self._picker = p

def set_pickradius(self, d):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did Patch not have set_pickradius before? I'm concerned about deprecating this and adding the replacement API in the same version.

"""
Set the pick radius used for containment tests.

Parameters
----------
d : float or None
The pick radius, in points. If None, the patch linewidth is used
as pickradius if the patch edge is not transparent.
"""
if not isinstance(d, Number) or d < 0:
raise ValueError("pick radius should be a distance")
self._pickradius = d

def get_pickradius(self):
"""
Return the pick radius used for containment tests.

Returns
-------
float or None
The pick radius, in points. If None, the patch linewidth is used
as pickradius if the patch edge is not transparent.
"""
return self._pickradius

def _process_radius(self, radius):
if radius is not None:
return radius
if isinstance(self._picker, Number):
_radius = self._picker
else:
if self.get_edgecolor()[3] == 0:
_radius = 0
else:
_radius = self.get_linewidth()
return _radius
return (
radius if radius is not None
else self._pickradius if self._pickradius is not None
# Deprecated case.
else self._picker if (isinstance(self._picker, Number)
and not isinstance(self._picker, bool))
else 0 if self.get_edgecolor()[3] == 0
else self.get_linewidth())

def contains(self, mouseevent, radius=None):
"""
Expand Down
2 changes: 1 addition & 1 deletion lib/matplotlib/tests/test_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ def test_hexbin_pickable():
fig, ax = plt.subplots()
data = (np.arange(200) / 200).reshape((2, 100))
x, y = data
hb = ax.hexbin(x, y, extent=[.1, .3, .6, .7], picker=-1)
hb = ax.hexbin(x, y, extent=[.1, .3, .6, .7], picker=True, pickradius=-1)
mouse_event = SimpleNamespace(x=400, y=300)
assert hb.contains(mouse_event)[0]

Expand Down
7 changes: 4 additions & 3 deletions lib/mpl_toolkits/tests/test_axes_grid1.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import matplotlib
import matplotlib.pyplot as plt
from matplotlib import cbook
from matplotlib import _api, cbook
from matplotlib.cbook import MatplotlibDeprecationWarning
from matplotlib.backend_bases import MouseEvent
from matplotlib.colors import LogNorm
Expand Down Expand Up @@ -409,8 +409,9 @@ def test_picking_callbacks_overlap(big_on_axes, small_on_axes, click_on):
# In each case we expect that both rectangles are picked if we click on the
# small one and only the big one is picked if we click on the big one.
# Also tests picking on normal axes ("gca") as a control.
big = plt.Rectangle((0.25, 0.25), 0.5, 0.5, picker=5)
small = plt.Rectangle((0.4, 0.4), 0.2, 0.2, facecolor="r", picker=5)
big = plt.Rectangle((0.25, 0.25), 0.5, 0.5, picker=True, pickradius=5)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you want to keep one of these for the test coverage?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure

with _api.suppress_matplotlib_deprecation_warning():
small = plt.Rectangle((0.4, 0.4), 0.2, 0.2, facecolor="r", picker=5)
# Machinery for "receiving" events
received_events = []
def on_pick(event):
Expand Down
0