diff --git a/lib/matplotlib/_pylab_helpers.py b/lib/matplotlib/_pylab_helpers.py index 57e6d985af22..4cb8be0a14f8 100644 --- a/lib/matplotlib/_pylab_helpers.py +++ b/lib/matplotlib/_pylab_helpers.py @@ -45,14 +45,23 @@ def get_fig_manager(cls, num): @classmethod def destroy(cls, num): """ - Destroy figure number *num*. + Destroy manager *num* -- either a manager instance or a manager number. In the interactive backends, this is bound to the window "destroy" and "delete" events. + + It is recommended to pass a manager instance, to avoid confusion when + two managers share the same number. """ - if not cls.has_fignum(num): - return - manager = cls.figs.pop(num) + if all(hasattr(num, attr) for attr in ["num", "_cidgcf", "destroy"]): + manager = num + if cls.figs.get(manager.num) is manager: + cls.figs.pop(manager.num) + else: + try: + manager = cls.figs.pop(num) + except KeyError: + return manager.canvas.mpl_disconnect(manager._cidgcf) manager.destroy() gc.collect(1) @@ -62,8 +71,7 @@ def destroy_fig(cls, fig): """Destroy figure *fig*.""" canvas = getattr(fig, "canvas", None) manager = getattr(canvas, "manager", None) - num = getattr(manager, "num", None) - cls.destroy(num) + cls.destroy(manager) @classmethod def destroy_all(cls): diff --git a/lib/matplotlib/backends/_backend_tk.py b/lib/matplotlib/backends/_backend_tk.py index 6556d104f382..a982385a87a2 100644 --- a/lib/matplotlib/backends/_backend_tk.py +++ b/lib/matplotlib/backends/_backend_tk.py @@ -456,7 +456,7 @@ def show(self): if not self._shown: def destroy(*args): self.window = None - Gcf.destroy(self.num) + Gcf.destroy(self) self.canvas._tkcanvas.bind("", destroy) self.window.deiconify() else: diff --git a/lib/matplotlib/backends/backend_gtk3.py b/lib/matplotlib/backends/backend_gtk3.py index 0e8dc97a48d8..1f9408b0668a 100644 --- a/lib/matplotlib/backends/backend_gtk3.py +++ b/lib/matplotlib/backends/backend_gtk3.py @@ -367,10 +367,8 @@ def add_widget(child): self.window.set_default_size(w, h) - def destroy(*args): - Gcf.destroy(num) - self.window.connect("destroy", destroy) - self.window.connect("delete_event", destroy) + self.window.connect("destroy", lambda *args: Gcf.destroy(self)) + self.window.connect("delete_event", lambda *args: Gcf.destroy(self)) if mpl.is_interactive(): self.window.show() self.canvas.draw_idle() diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index 31bf8a4cb947..84d2ec11492c 100644 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -106,7 +106,7 @@ def __init__(self, canvas, num): self.canvas.draw_idle() def close(self): - Gcf.destroy(self.num) + Gcf.destroy(self) class NavigationToolbar2Mac(_macosx.NavigationToolbar2, NavigationToolbar2): diff --git a/lib/matplotlib/backends/backend_nbagg.py b/lib/matplotlib/backends/backend_nbagg.py index c61d2a13d86b..49e3d514ad03 100644 --- a/lib/matplotlib/backends/backend_nbagg.py +++ b/lib/matplotlib/backends/backend_nbagg.py @@ -231,7 +231,7 @@ def new_figure_manager_given_figure(num, figure): if is_interactive(): manager.show() figure.canvas.draw_idle() - canvas.mpl_connect('close_event', lambda event: Gcf.destroy(num)) + canvas.mpl_connect('close_event', lambda event: Gcf.destroy(manager)) return manager @staticmethod diff --git a/lib/matplotlib/backends/backend_qt5.py b/lib/matplotlib/backends/backend_qt5.py index 46b684bba928..5c657bf5b2a2 100644 --- a/lib/matplotlib/backends/backend_qt5.py +++ b/lib/matplotlib/backends/backend_qt5.py @@ -590,7 +590,7 @@ def _widgetclosed(self): return self.window._destroying = True try: - Gcf.destroy(self.num) + Gcf.destroy(self) except AttributeError: pass # It seems that when the python session is killed, diff --git a/lib/matplotlib/backends/backend_wx.py b/lib/matplotlib/backends/backend_wx.py index e48e7cf45f29..e8635df49aa5 100644 --- a/lib/matplotlib/backends/backend_wx.py +++ b/lib/matplotlib/backends/backend_wx.py @@ -1007,7 +1007,7 @@ def _onClose(self, event): _log.debug("%s - onClose()", type(self)) self.canvas.close_event() self.canvas.stop_event_loop() - Gcf.destroy(self.num) + Gcf.destroy(self) # self.Destroy() def GetToolBar(self): diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index 63a267ae4583..bce356516fdd 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -690,7 +690,7 @@ def close(fig=None): if figManager is None: return else: - _pylab_helpers.Gcf.destroy(figManager.num) + _pylab_helpers.Gcf.destroy(figManager) elif fig == 'all': _pylab_helpers.Gcf.destroy_all() elif isinstance(fig, int):