|
20 | 20 |
|
21 | 21 | _log = logging.getLogger(__name__) |
22 | 22 |
|
| 23 | +# a tombstone sentinel to ensure we never reset the axes or figure on an Artist |
| 24 | +_tombstone = object() |
| 25 | + |
23 | 26 |
|
24 | 27 | def _prevent_rasterization(draw): |
25 | 28 | # We assume that by default artists are not allowed to rasterize (unless |
@@ -181,7 +184,7 @@ def __init__(self): |
181 | 184 | self._stale = True |
182 | 185 | self.stale_callback = None |
183 | 186 | self._axes = None |
184 | | - self.figure = None |
| 187 | + self._figure = None |
185 | 188 |
|
186 | 189 | self._transform = None |
187 | 190 | self._transformSet = False |
@@ -293,18 +296,60 @@ def convert_yunits(self, y): |
293 | 296 | @property |
294 | 297 | def axes(self): |
295 | 298 | """The `~.axes.Axes` instance the artist resides in, or *None*.""" |
296 | | - return self._axes |
| 299 | + return self._axes if self._axes is not _tombstone else None |
297 | 300 |
|
298 | 301 | @axes.setter |
299 | 302 | def axes(self, new_axes): |
300 | 303 | if (new_axes is not None and self._axes is not None |
301 | 304 | and new_axes != self._axes): |
302 | | - raise ValueError("Can not reset the Axes. You are probably trying to reuse " |
303 | | - "an artist in more than one Axes which is not supported") |
| 305 | + if self._axes is _tombstone: |
| 306 | + extra = ( |
| 307 | + f"The artist {self!r} has had its Axes reset to None " + |
| 308 | + "but was previously included in one." |
| 309 | + ) |
| 310 | + else: |
| 311 | + extra = ( |
| 312 | + f"The artist {self!r} is currently in {self._axes!r} " + |
| 313 | + f"in the figure {self._axes.figure!r}." |
| 314 | + ) |
| 315 | + raise ValueError("Can not reset the Axes. You are probably " + |
| 316 | + "trying to re-use an artist in more than one " + |
| 317 | + "Axes which is not supported. " + |
| 318 | + extra |
| 319 | + ) |
| 320 | + if self._axes is not None and new_axes is None: |
| 321 | + new_axes = _tombstone |
304 | 322 | self._axes = new_axes |
305 | 323 | if new_axes is not None and new_axes is not self: |
306 | 324 | self.stale_callback = _stale_axes_callback |
307 | 325 |
|
| 326 | + @property |
| 327 | + def figure(self): |
| 328 | + """The `~.figure.Figure` instance the artist resides in, or *None*.""" |
| 329 | + return self._figure if self._figure is not _tombstone else None |
| 330 | + |
| 331 | + @figure.setter |
| 332 | + def figure(self, new_figure): |
| 333 | + if (new_figure is not None and self._figure is not None |
| 334 | + and new_figure != self._figure and new_figure is not True): |
| 335 | + if self._figure is _tombstone: |
| 336 | + extra = ( |
| 337 | + f"The artist {self!r} has had its Figure reset to None " + |
| 338 | + "but was previously included in one." |
| 339 | + ) |
| 340 | + else: |
| 341 | + extra = ( |
| 342 | + f"The artist {self!r} is currently in {self._figure!r}." |
| 343 | + ) |
| 344 | + raise ValueError("Can not reset the figure. You are probably " + |
| 345 | + "trying to re-use an artist in more than one " + |
| 346 | + "Figure which is not supported. " + |
| 347 | + extra |
| 348 | + ) |
| 349 | + if self._figure is not None and new_figure is None: |
| 350 | + new_figure = _tombstone |
| 351 | + self._figure = new_figure |
| 352 | + |
308 | 353 | @property |
309 | 354 | def stale(self): |
310 | 355 | """ |
@@ -738,14 +783,6 @@ def set_figure(self, fig): |
738 | 783 | # if this is a no-op just return |
739 | 784 | if self.figure is fig: |
740 | 785 | return |
741 | | - # if we currently have a figure (the case of both `self.figure` |
742 | | - # and *fig* being none is taken care of above) we then user is |
743 | | - # trying to change the figure an artist is associated with which |
744 | | - # is not allowed for the same reason as adding the same instance |
745 | | - # to more than one Axes |
746 | | - if self.figure is not None: |
747 | | - raise RuntimeError("Can not put single artist in " |
748 | | - "more than one figure") |
749 | 786 | self.figure = fig |
750 | 787 | if self.figure and self.figure is not self: |
751 | 788 | self.pchanged() |
|
0 commit comments