|
16 | 16 | import functools
|
17 | 17 | import logging
|
18 | 18 | import warnings
|
19 |
| -from weakref import WeakKeyDictionary |
| 19 | +import weakref |
20 | 20 |
|
21 | 21 | from matplotlib.backend_bases import FigureCanvasBase as _FigureCanvasBase
|
22 | 22 |
|
@@ -70,7 +70,7 @@ def show(figs, *, block=None, timeout=0):
|
70 | 70 | if fig.canvas.manager is not None:
|
71 | 71 | managers.append(fig.canvas.manager)
|
72 | 72 | else:
|
73 |
| - managers.append(promote_figure(fig)) |
| 73 | + managers.append(promote_figure(fig, num=None)) |
74 | 74 |
|
75 | 75 | if block is None:
|
76 | 76 | block = not is_interactive()
|
@@ -117,33 +117,41 @@ def __init__(self, *, block=None, timeout=0, prefix="Figure "):
|
117 | 117 | # settings stashed to set defaults on show
|
118 | 118 | self._timeout = timeout
|
119 | 119 | self._block = block
|
120 |
| - # Settings / state to control the default figure label |
121 |
| - self._fig_to_number = WeakKeyDictionary() |
122 |
| - self._prefix = prefix |
123 | 120 | # the canonical location for storing the Figures this registry owns.
|
124 |
| - # any additional views must never include a figure not in the list but |
| 121 | + # any additional views must never include a figure that is not a key but |
125 | 122 | # may omit figures
|
126 |
| - self.figures = [] |
| 123 | + self._fig_to_number = dict() |
| 124 | + # Settings / state to control the default figure label |
| 125 | + self._prefix = prefix |
| 126 | + |
| 127 | + @property |
| 128 | + def figures(self): |
| 129 | + return tuple(self._fig_to_number) |
127 | 130 |
|
128 | 131 | def _register_fig(self, fig):
|
129 | 132 | # if the user closes the figure by any other mechanism, drop our
|
130 | 133 | # reference to it. This is important for getting a "pyplot" like user
|
131 | 134 | # experience
|
132 |
| - fig.canvas.mpl_connect( |
133 |
| - "close_event", |
134 |
| - lambda e: self.figures.remove(fig) if fig in self.figures else None, |
135 |
| - ) |
136 |
| - # hold a hard reference to the figure. |
137 |
| - self.figures.append(fig) |
| 135 | + def registry_cleanup(fig_wr): |
| 136 | + fig = fig_wr() |
| 137 | + if fig is not None: |
| 138 | + if fig.canvas is not None: |
| 139 | + fig.canvas.mpl_disconnect(cid) |
| 140 | + self.close(fig) |
| 141 | + |
| 142 | + fig_wr = weakref.ref(fig) |
| 143 | + cid = fig.canvas.mpl_connect("close_event", lambda e: registry_cleanup(fig_wr)) |
138 | 144 | # Make sure we give the figure a quasi-unique label. We will never set
|
139 | 145 | # the same label twice, but will not over-ride any user label (but
|
140 | 146 | # empty string) on a Figure so if they provide duplicate labels, change
|
141 | 147 | # the labels under us, or provide a label that will be shadowed in the
|
142 | 148 | # future it will be what it is.
|
143 |
| - fignum = max(self._fig_to_number.values(), default=0) + 1 |
| 149 | + fignum = max(self._fig_to_number.values(), default=-1) + 1 |
144 | 150 | if fig.get_label() == "":
|
145 | 151 | fig.set_label(f"{self._prefix}{fignum:d}")
|
146 | 152 | self._fig_to_number[fig] = fignum
|
| 153 | + if is_interactive(): |
| 154 | + promote_figure(fig, num=fignum) |
147 | 155 | return fig
|
148 | 156 |
|
149 | 157 | @property
|
@@ -302,8 +310,7 @@ def close(self, val):
|
302 | 310 | # disconnect canvas from figure
|
303 | 311 | _FigureCanvasBase(figure=fig)
|
304 | 312 | assert fig.canvas.manager is None
|
305 |
| - if fig in self.figures: |
306 |
| - self.figures.remove(fig) |
| 313 | + self._fig_to_number.pop(fig, None) |
307 | 314 |
|
308 | 315 |
|
309 | 316 | class FigureContext(FigureRegistry):
|
|
0 commit comments