0

I'm trying to create an animated figure for showing multiple tens of thousands of data points, appearing over time, in a single figure. Using blit=True to avoid redrawing everything every frame doesn't work without telling it to redraw everything every frame - I want to just draw the new data points.

Neither python matplotlib update scatter plot from a function or How to animate a scatter plot? answer the question because I want to add new artists, not just update existing ones with set_offsets, which forces every point to be redrawn. The documentation says that it does support new artists:

func must return an iterable of all artists that were modified or created

I'm running matplotlib 3.1.1 on macOS 10.13 and RHEL7 - the MacOSX backend doesn't work at all for me with blitting, so manually selecting TkAgg on that system:

import matplotlib matplotlib.use("TkAgg") # On macOS import matplotlib.animation as animation import matplotlib.pyplot as plt def animate(n): scatter = ax1.scatter([n], [n]) return [scatter] fig = plt.figure() ax1 = fig.add_subplot(111) ax1.set_xlim(0, 20) ax1.set_ylim(0, 20) ani = animation.FuncAnimation(fig, animate, interval=100, blit=True) plt.show() 

But when running this, only the last plotted data point remains on the figure: Animation only showing single artist

How can I use blitting to write new data points without drawing everything every frame?

6
  • Have a look here (stackoverflow.com/a/42738014/10640534) and here (stackoverflow.com/a/43680172/10640534). Commented Oct 8, 2019 at 23:07
  • Yes, I viewed both of those, and both are answering different questions. Neither of them handle a) blitting or b) adding new artists. If I update an existing artist, all X0,000 points are redrawn every frame, which quickly becomes very slow. Commented Oct 9, 2019 at 8:01
  • I've updated the question to hopefully make it clearer that neither of those questions actually answer it, just answer a different question about the same topic Commented Oct 9, 2019 at 8:23
  • Would the following work for you then? import matplotlib.animation as animation import matplotlib.pyplot as plt def animate(n): scatter = ax.scatter(n, n) if n == 0: return ax.get_children()[0], else: return ax.get_children()[:n] fig, ax = plt.subplots() ax.set_xlim(0, 20) ax.set_ylim(0, 20) ani = animation.FuncAnimation(fig, animate, interval=100, blit=True) plt.show() Commented Oct 9, 2019 at 12:00
  • After further research, I think this isn't actually possible like I want - I dove into the animation code and it deliberately clears the axis back to the original every frame. Looks like the standard animation classes are just for drawing on top of a complicated base. I have an example of it working which is why I thought it was possible, but I think that is accidentally causing a refresh anyway. I'll self-answer when I'm a bit more certain. Commented Oct 9, 2019 at 12:08

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.