Skip to content

Commit be93150

Browse files
committed
Merge pull request #4878 from tacaswell/prf_mouse_move_event
PRF: only check some artists on mousemove
2 parents 4531ff7 + ded655a commit be93150

File tree

5 files changed

+69
-4
lines changed

5 files changed

+69
-4
lines changed

lib/matplotlib/artist.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def __init__(self):
101101
self._contains = None
102102
self._rasterized = None
103103
self._agg_filter = None
104-
104+
self._mouseover = False
105105
self.eventson = False # fire events only if eventson
106106
self._oid = 0 # an observer id
107107
self._propobservers = {} # a dict from oids to funcs
@@ -146,6 +146,23 @@ def remove(self):
146146
# callback has one parameter, which is the child to be removed.
147147
if self._remove_method is not None:
148148
self._remove_method(self)
149+
# clear stale callback
150+
self.stale_callback = None
151+
_ax_flag = False
152+
if hasattr(self, 'axes') and self.axes:
153+
# remove from the mouse hit list
154+
self.axes.mouseover_set.discard(self)
155+
# mark the axes as stale
156+
self.axes.stale = True
157+
# decouple the artist from the axes
158+
self.axes = None
159+
_ax_flag = True
160+
161+
if self.figure:
162+
self.figure = None
163+
if not _ax_flag:
164+
self.figure = True
165+
149166
else:
150167
raise NotImplementedError('cannot remove artist')
151168
# TODO: the fix for the collections relim problem is to move the
@@ -213,7 +230,9 @@ def axes(self):
213230

214231
@axes.setter
215232
def axes(self, new_axes):
216-
if self._axes is not None and new_axes != self._axes:
233+
234+
if (new_axes is not None and
235+
(self._axes is not None and new_axes != self._axes)):
217236
raise ValueError("Can not reset the axes. You are "
218237
"probably trying to re-use an artist "
219238
"in more than one Axes which is not "
@@ -971,6 +990,21 @@ def format_cursor_data(self, data):
971990
data = [data]
972991
return ', '.join('{:0.3g}'.format(item) for item in data)
973992

993+
@property
994+
def mouseover(self):
995+
return self._mouseover
996+
997+
@mouseover.setter
998+
def mouseover(self, val):
999+
val = bool(val)
1000+
self._mouseover = val
1001+
ax = self.axes
1002+
if ax:
1003+
if val:
1004+
ax.mouseover_set.add(self)
1005+
else:
1006+
ax.mouseover_set.discard(self)
1007+
9741008

9751009
class ArtistInspector(object):
9761010
"""

lib/matplotlib/axes/_base.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,8 @@ def _set_artist_props(self, a):
786786
a.set_transform(self.transData)
787787

788788
a.axes = self
789+
if a.mouseover:
790+
self.mouseover_set.add(a)
789791

790792
def _gen_axes_patch(self):
791793
"""
@@ -916,6 +918,7 @@ def cla(self):
916918
self.tables = []
917919
self.artists = []
918920
self.images = []
921+
self.mouseover_set = set()
919922
self._current_image = None # strictly for pyplot via _sci, _gci
920923
self.legend_ = None
921924
self.collections = [] # collection.Collection instances

lib/matplotlib/backend_bases.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2825,9 +2825,11 @@ def mouse_move(self, event):
28252825
except (ValueError, OverflowError):
28262826
pass
28272827
else:
2828-
artists = event.inaxes.hitlist(event)
2828+
artists = [a for a in event.inaxes.mouseover_set
2829+
if a.contains(event)]
28292830

28302831
if artists:
2832+
28312833
a = max(enumerate(artists), key=lambda x: x[1].zorder)[1]
28322834
if a is not event.inaxes.patch:
28332835
data = a.get_cursor_data(event)

lib/matplotlib/image.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def __init__(self, ax,
107107
"""
108108
martist.Artist.__init__(self)
109109
cm.ScalarMappable.__init__(self, norm, cmap)
110-
110+
self._mouseover = True
111111
if origin is None:
112112
origin = rcParams['image.origin']
113113
self.origin = origin

lib/matplotlib/tests/test_artist.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import matplotlib.collections as mcollections
1515
from matplotlib.testing.decorators import image_comparison, cleanup
1616

17+
from nose.tools import (assert_true, assert_false)
18+
1719

1820
@cleanup
1921
def test_patch_transform_of_none():
@@ -144,6 +146,30 @@ def test_cull_markers():
144146
assert len(svg.getvalue()) < 20000
145147

146148

149+
@cleanup
150+
def test_remove():
151+
fig, ax = plt.subplots()
152+
im = ax.imshow(np.arange(36).reshape(6, 6))
153+
154+
assert_true(fig.stale)
155+
assert_true(ax.stale)
156+
157+
fig.canvas.draw()
158+
assert_false(fig.stale)
159+
assert_false(ax.stale)
160+
161+
assert_true(im in ax.mouseover_set)
162+
assert_true(im.axes is ax)
163+
164+
im.remove()
165+
166+
assert_true(im.axes is None)
167+
assert_true(im.figure is None)
168+
assert_true(im not in ax.mouseover_set)
169+
assert_true(fig.stale)
170+
assert_true(ax.stale)
171+
172+
147173
if __name__ == '__main__':
148174
import nose
149175
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)

0 commit comments

Comments
 (0)