diff --git a/lib/matplotlib/artist.py b/lib/matplotlib/artist.py index 1b696813abc8..f6472b0704e4 100644 --- a/lib/matplotlib/artist.py +++ b/lib/matplotlib/artist.py @@ -119,8 +119,7 @@ def __init__(self): # only if they override get_cursor_data. self._mouseover = type(self).get_cursor_data != Artist.get_cursor_data self.eventson = False # fire events only if eventson - self._oid = 0 # an observer id - self._propobservers = {} # a dict from oids to funcs + self._callbacks = cbook.CallbackRegistry() try: self.axes = None except AttributeError: @@ -341,10 +340,9 @@ def func(artist: Artist) -> Any -------- remove_callback """ - oid = self._oid - self._propobservers[oid] = func - self._oid += 1 - return oid + # Wrapping func in a lambda ensures it can be connected multiple times + # and never gets weakref-gc'ed. + return self._callbacks.connect("pchanged", lambda: func(self)) def remove_callback(self, oid): """ @@ -354,10 +352,7 @@ def remove_callback(self, oid): -------- add_callback """ - try: - del self._propobservers[oid] - except KeyError: - pass + self._callbacks.disconnect("pchanged", oid) def pchanged(self): """ @@ -370,8 +365,7 @@ def pchanged(self): add_callback remove_callback """ - for oid, func in self._propobservers.items(): - func(self) + self._callbacks.process("pchanged") def is_transform_set(self): """ diff --git a/lib/matplotlib/container.py b/lib/matplotlib/container.py index ab2723b012dd..97c3ac4dec15 100644 --- a/lib/matplotlib/container.py +++ b/lib/matplotlib/container.py @@ -19,8 +19,7 @@ def __new__(cls, *args, **kwargs): def __init__(self, kl, label=None): self.eventson = False # fire events only if eventson - self._oid = 0 # an observer id - self._propobservers = {} # a dict from oids to funcs + self._callbacks = cbook.CallbackRegistry() self._remove_method = None self.set_label(label) @@ -29,7 +28,6 @@ def remove(self): self, scalarp=lambda x: isinstance(x, Artist)): if c is not None: c.remove() - if self._remove_method: self._remove_method(self)