You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
MacOSX does not render frames in which new artists are added when blitting #17445
Using FuncAnimation with the MacOSX backend and blitting turned on, every frame in which a new artist or patch is added to the axes is blank, while all other frames render normally. This does not happen with the TkAgg backend, and presumable MacOSX is the only affected backend.
I run into a similar bug with macOS Catalina as well as with Big Sur and matplotlib 3.3.2.
I try to set the positions of a PathCollection (scatter) for every frame. Furthermore, I create new quiver for every frame.
The corresponding code can be found here.
With this setup I experience the same issue as described above. Only in my case none of the mentioned artists is rendered at all. Probably because I update them for every frame.
@tacaswell sure thing.
The example should show a marker moving smoothly from [0, 0] to [1, 1] along an arrow.
It works with the TkAgg backend but not with MacOSX. With the latter one neither a marker nor arrow is shown.
Details
importmatplotlib.pyplotaspltfrommatplotlibimportanimationimportnumpyasnpclassBaseVisualizer():
def__init__(self, **kwargs):
self.__iteration_number=kwargs.get('iteration_number', 1)
self.__intervals=1self.__interval_ms=kwargs.get('interval', 2000)
self._marker_size=4self._index=0self._positions=np.zeros(2)
self._velocities=np.ones(2)
self.__frame_interval=50# msdefreplay(self):
self._fig=plt.figure()
ax=self._fig.add_subplot(1, 1, 1, label='BaseAxis')
# Plot all particle posself.__particles=ax.scatter([], [], marker='o', zorder=2, color='red')
# Plot all velocitiesself.__particle_vel=ax.quiver([], [], [], [], angles='xy', scale_units='xy', scale=1)
self.__rectangle=plt.Rectangle([0,0], 1, 1, ec='none', lw=2, fc='none')
ax.add_patch(self.__rectangle)
# Amount of frames to play considering one interval should last __interval ms.frames=int(self.__intervals*self.__interval_ms/self.__frame_interval)
# iteration_number+1 for initialization frame_=animation.FuncAnimation(self._fig, self._animate, frames=frames, interval=self.__frame_interval,
blit=True, repeat=False, fargs=[frames])
plt.show()
def_animate(self, i: int, frames: int):
""" Animation function for animations. Only used for FuncAnimation """self._marker_size=int(50*self._fig.get_figwidth()/self._fig.dpi)
# Calculate the scale to apply to the data in order to generate a more dynamic visualizationscale=i/ (frames/self.__intervals)
# Calculate scaled position and velocitypos_scaled=self._positions+scale*self._velocitiesvel_scaled= (1-scale)*self._velocities# Update the particle positionself.__particles.set_offsets(pos_scaled)
self.__particles.set_sizes([self._marker_size**2])
# Update the velocitiesax=self._fig.gca(label='BaseAxis')
self.__particle_vel=ax.quiver(pos_scaled[0], pos_scaled[1], vel_scaled[0], vel_scaled[1], angles='xy', scale_units='xy', scale=1, color='#CFCFCF', width=self._marker_size*0.001)
returnself.__particles, self.__particle_velif__name__=='__main__':
vis=BaseVisualizer()
vis.replay()
to the top of replay how many times does it print 'Drawing'? My guess is that something about the osx backend is triggering an extra full-draw when an artist is added. However, when you are using blitting the animated artists are excluded from that draw pass (so that we can get a "clean" background image to animate on top of). If the order is "add artists, updating via blitting, re-draw!", then you will see blank frames when new artists are added.
Activity
HaaLeo commentedon Nov 16, 2020
I run into a similar bug with macOS Catalina as well as with Big Sur and matplotlib 3.3.2.
I try to set the positions of a
PathCollection(scatter) for every frame. Furthermore, I create newquiverfor every frame.The corresponding code can be found here.
With this setup I experience the same issue as described above. Only in my case none of the mentioned artists is rendered at all. Probably because I update them for every frame.
tacaswell commentedon Nov 16, 2020
@mfosterw Does it work if you do
fig.stale_callback = Nonebefore starting the animation does it solve the problem?@HaaLeo Can you reduce your problem to a minimal reproducible example?
HaaLeo commentedon Nov 16, 2020
@tacaswell sure thing.
The example should show a marker moving smoothly from
[0, 0]to[1, 1]along an arrow.It works with the
TkAggbackend but not withMacOSX. With the latter one neither a marker nor arrow is shown.Details
HaaLeo commentedon Nov 25, 2020
@tacaswell can you reproduce the error with the sample code above?
tacaswell commentedon Nov 25, 2020
Thank you for re-upping this, I missed your initial reply.
@HaaLeo I can not reproduce the issue (but I do not have a mac). Can you try the
fig.stale_callback = None?If you add
to the top of
replayhow many times does it print 'Drawing'? My guess is that something about the osx backend is triggering an extra full-draw when an artist is added. However, when you are using blitting the animated artists are excluded from that draw pass (so that we can get a "clean" background image to animate on top of). If the order is "add artists, updating via blitting, re-draw!", then you will see blank frames when new artists are added.attn @dopplershift
ps, that is a very cool example.
HaaLeo commentedon Nov 25, 2020
@tacaswell thx for your fast reply (and the feedback on the example 😉)
I updated the example above with the following lines:
With the
MacOSXbackend it prints 41 timesDrawing!. With theTkAggbackend only three times.Adding
self._fig.stale_callback = Nonedoes not change that behavior.tacaswell commentedon Nov 25, 2020
Ok, so that confirms my guess as to why we get a blank screen and changes the question to "Why is OSX drawing 41 times?!".