|
51 | 51 | docstring.interpd.update(projection_names=get_projection_names())
|
52 | 52 |
|
53 | 53 |
|
| 54 | +def _stale_figure_callback(self, val): |
| 55 | + if self.figure: |
| 56 | + self.figure.stale = val |
| 57 | + |
| 58 | + |
54 | 59 | class AxesStack(Stack):
|
55 | 60 | """
|
56 | 61 | Specialization of the Stack to handle all tracking of Axes in a Figure.
|
@@ -330,6 +335,7 @@ def __init__(self,
|
330 | 335 | xy=(0, 0), width=1, height=1,
|
331 | 336 | facecolor=facecolor, edgecolor=edgecolor,
|
332 | 337 | linewidth=linewidth)
|
| 338 | + |
333 | 339 | self._set_artist_props(self.patch)
|
334 | 340 | self.patch.set_aa(False)
|
335 | 341 |
|
@@ -543,6 +549,7 @@ def suptitle(self, t, **kwargs):
|
543 | 549 | sup.remove()
|
544 | 550 | else:
|
545 | 551 | self._suptitle = sup
|
| 552 | + |
546 | 553 | self.stale = True
|
547 | 554 | return self._suptitle
|
548 | 555 |
|
@@ -650,6 +657,8 @@ def figimage(self, X,
|
650 | 657 | self.set_size_inches(figsize, forward=True)
|
651 | 658 |
|
652 | 659 | im = FigureImage(self, cmap, norm, xo, yo, origin, **kwargs)
|
| 660 | + im.stale_callback = _stale_figure_callback |
| 661 | + |
653 | 662 | im.set_array(X)
|
654 | 663 | im.set_alpha(alpha)
|
655 | 664 | if norm is None:
|
@@ -910,6 +919,7 @@ def add_axes(self, *args, **kwargs):
|
910 | 919 | self.sca(a)
|
911 | 920 | a._remove_method = lambda ax: self.delaxes(ax)
|
912 | 921 | self.stale = True
|
| 922 | + a.stale_callback = _stale_figure_callback |
913 | 923 | return a
|
914 | 924 |
|
915 | 925 | @docstring.dedent_interpd
|
@@ -999,6 +1009,7 @@ def add_subplot(self, *args, **kwargs):
|
999 | 1009 | self.sca(a)
|
1000 | 1010 | a._remove_method = lambda ax: self.delaxes(ax)
|
1001 | 1011 | self.stale = True
|
| 1012 | + a.stale_callback = _stale_figure_callback |
1002 | 1013 | return a
|
1003 | 1014 |
|
1004 | 1015 | def clf(self, keep_observers=False):
|
@@ -1046,8 +1057,10 @@ def draw(self, renderer):
|
1046 | 1057 | # draw the figure bounding box, perhaps none for white figure
|
1047 | 1058 | if not self.get_visible():
|
1048 | 1059 | return
|
1049 |
| - renderer.open_group('figure') |
1050 | 1060 |
|
| 1061 | + renderer.open_group('figure') |
| 1062 | + # prevent triggering call backs during the draw process |
| 1063 | + self._stale = True |
1051 | 1064 | if self.get_tight_layout() and self.axes:
|
1052 | 1065 | try:
|
1053 | 1066 | self.tight_layout(renderer, **self._tight_parameters)
|
@@ -1119,12 +1132,11 @@ def draw_composite():
|
1119 | 1132 | dsu.sort(key=itemgetter(0))
|
1120 | 1133 | for zorder, a, func, args in dsu:
|
1121 | 1134 | func(*args)
|
1122 |
| - a.stale = False |
1123 | 1135 |
|
1124 | 1136 | renderer.close_group('figure')
|
| 1137 | + self.stale = False |
1125 | 1138 |
|
1126 | 1139 | self._cachedRenderer = renderer
|
1127 |
| - self.stale = False |
1128 | 1140 | self.canvas.draw_event(renderer)
|
1129 | 1141 |
|
1130 | 1142 | def draw_artist(self, a):
|
@@ -1274,6 +1286,7 @@ def text(self, x, y, s, *args, **kwargs):
|
1274 | 1286 | def _set_artist_props(self, a):
|
1275 | 1287 | if a != self:
|
1276 | 1288 | a.set_figure(self)
|
| 1289 | + a.stale_callback = _stale_figure_callback |
1277 | 1290 | a.set_transform(self.transFigure)
|
1278 | 1291 |
|
1279 | 1292 | @docstring.dedent_interpd
|
@@ -1350,7 +1363,7 @@ def _gci(self):
|
1350 | 1363 | return None
|
1351 | 1364 |
|
1352 | 1365 | def __getstate__(self):
|
1353 |
| - state = self.__dict__.copy() |
| 1366 | + state = super(Figure, self).__getstate__() |
1354 | 1367 | # the axobservers cannot currently be pickled.
|
1355 | 1368 | # Additionally, the canvas cannot currently be pickled, but this has
|
1356 | 1369 | # the benefit of meaning that a figure can be detached from one canvas,
|
|
0 commit comments