-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
MNT: overhaul stale handling #4738
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
02158b1
b0c3741
7f3ef65
a677634
6d6e39a
1aec54b
1a58f17
72c5ce2
4cc9a74
b39fd90
0b49a55
59eaad6
69b1b36
770b8d5
aa810b6
0af89d7
14b5a36
252d7a7
a44b74d
53e2db2
54e04d3
5bd4711
a48be9f
13e7c09
83ea020
a5f5ab5
c75f75d
51cc0ca
0e201f9
25079bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -971,17 +971,18 @@ def __init__(self, fig, artists, *args, **kwargs): | |
|
||
def _init_draw(self): | ||
# Make all the artists involved in *any* frame invisible | ||
axes = [] | ||
figs = set() | ||
for f in self.new_frame_seq(): | ||
for artist in f: | ||
artist.set_visible(False) | ||
artist.set_animated(self._blit) | ||
# Assemble a list of unique axes that need flushing | ||
if artist.axes not in axes: | ||
axes.append(artist.axes) | ||
if artist.axes.figure not in figs: | ||
figs.add(artist.axes.figure) | ||
|
||
# Flush the needed axes | ||
for ax in axes: | ||
ax.figure.canvas.draw() | ||
for fig in figs: | ||
fig.canvas.draw() | ||
|
||
def _pre_draw(self, framedata, blit): | ||
''' | ||
|
@@ -1093,6 +1094,8 @@ def _init_draw(self): | |
self._draw_frame(next(self.new_frame_seq())) | ||
else: | ||
self._drawn_artists = self._init_func() | ||
for a in self._drawn_artists: | ||
a.set_animated(self._blit) | ||
|
||
def _draw_frame(self, framedata): | ||
# Save the data for potential saving of movies. | ||
|
@@ -1105,3 +1108,5 @@ def _draw_frame(self, framedata): | |
# Call the func with framedata and args. If blitting is desired, | ||
# func needs to return a sequence of any artists that were modified. | ||
self._drawn_artists = self._func(framedata, *self._args) | ||
for a in self._drawn_artists: | ||
a.set_animated(self._blit) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this going to wreak havoc on the stale-handling code? Don't we want to avoid setting artists as stale within drawing code paths? |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -68,12 +68,9 @@ def draw_wrapper(artist, renderer, *args, **kwargs): | |
return draw_wrapper | ||
|
||
|
||
def _stale_figure_callback(self): | ||
self.figure.stale = True | ||
|
||
|
||
def _stale_axes_callback(self): | ||
self.axes.stale = True | ||
def _stale_axes_callback(self, val): | ||
if self.axes: | ||
self.axes.stale = val | ||
|
||
|
||
class Artist(object): | ||
|
@@ -87,6 +84,7 @@ class Artist(object): | |
|
||
def __init__(self): | ||
self._stale = True | ||
self.stale_callback = None | ||
self._axes = None | ||
self.figure = None | ||
|
||
|
@@ -124,6 +122,7 @@ def __getstate__(self): | |
# remove the unpicklable remove method, this will get re-added on load | ||
# (by the axes) if the artist lives on an axes. | ||
d['_remove_method'] = None | ||
d['stale_callback'] = None | ||
return d | ||
|
||
def remove(self): | ||
|
@@ -222,7 +221,7 @@ def axes(self, new_axes): | |
|
||
self._axes = new_axes | ||
if new_axes is not None and new_axes is not self: | ||
self.add_callback(_stale_axes_callback) | ||
self.stale_callback = _stale_axes_callback | ||
|
||
return new_axes | ||
|
||
|
@@ -236,15 +235,16 @@ def stale(self): | |
|
||
@stale.setter | ||
def stale(self, val): | ||
# only trigger call-back stack on being marked as 'stale' | ||
# when not already stale | ||
# the draw process will take care of propagating the cleaning | ||
# process | ||
if not (self._stale == val): | ||
self._stale = val | ||
# only trigger propagation if marking as stale | ||
if self._stale: | ||
self.pchanged() | ||
self._stale = val | ||
|
||
# if the artist is animated it does not take normal part in the | ||
# draw stack and is not expected to be drawn as part of the normal | ||
# draw loop (when not saving) so do not propagate this change | ||
if self.get_animated(): | ||
return | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it still going to be possible to change the properties of an animated object? I typically do things like changing the alpha or color as part of an animation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIRC, the animated bit on an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The stale handler does not propagate on animated artists, but you can still I am a bit worried about saving, i suspect that should also be checked in On Wed, Aug 12, 2015, 11:33 AM Benjamin Root [email protected]
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will revert the set change when i get back to my normal computer. On Wed, Aug 12, 2015, 11:43 AM Thomas Caswell [email protected] wrote:
|
||
|
||
if val and self.stale_callback is not None: | ||
self.stale_callback(self, val) | ||
|
||
def get_window_extent(self, renderer): | ||
""" | ||
|
@@ -608,9 +608,19 @@ def set_figure(self, fig): | |
|
||
ACCEPTS: a :class:`matplotlib.figure.Figure` instance | ||
""" | ||
# if this is a no-op just return | ||
if self.figure is fig: | ||
return | ||
# if we currently have a figure (the case of both `self.figure` | ||
# and `fig` being none is taken care of above) we then user is | ||
# trying to change the figure an artist is associated with which | ||
# is not allowed for the same reason as adding the same instance | ||
# to more than one Axes | ||
if self.figure is not None: | ||
raise RuntimeError("Can not put single artist in " | ||
"more than one figure") | ||
self.figure = fig | ||
if self.figure and self.figure is not self: | ||
self.add_callback(_stale_figure_callback) | ||
self.pchanged() | ||
self.stale = True | ||
|
||
|
@@ -804,9 +814,9 @@ def set_animated(self, b): | |
|
||
ACCEPTS: [True | False] | ||
""" | ||
self._animated = b | ||
self.pchanged() | ||
self.stale = True | ||
if self._animated != b: | ||
self._animated = b | ||
self.pchanged() | ||
|
||
def update(self, props): | ||
""" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -475,7 +475,7 @@ def __setstate__(self, state): | |
container = getattr(self, container_name) | ||
for artist in container: | ||
artist._remove_method = container.remove | ||
self.stale = True | ||
self._stale = True | ||
|
||
def get_window_extent(self, *args, **kwargs): | ||
""" | ||
|
@@ -2059,7 +2059,8 @@ def draw(self, renderer=None, inframe=False): | |
if not self.get_visible(): | ||
return | ||
renderer.open_group('axes') | ||
|
||
# prevent triggering call backs during the draw process | ||
self._stale = True | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure I understand why drawing would need to set stale flag to True. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can probably be removed now that stale state always propagates (which I am not 100% happy with) and with the context manager in |
||
locator = self.get_axes_locator() | ||
if locator: | ||
pos = locator(self, renderer) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wait a minute... figures are mutable. How is it that we can have a set of them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch on that and because i bet it is defaulting to using the object id
On Wed, Aug 12, 2015, 11:27 AM Benjamin Root [email protected]
wrote: