Can you help me speed up my animation?

Hi all,
I made a Jupyter notebook to reproduce the awesome Washington Post article on social distancing (linked near the top of the next two links because apparently I can only include two links in a post). You can see it here and you can see the actual notebook here. My apologies if it’s not the prettiest code, but hopefully it’s not too atrocious. Anyway, now on to my question:

The code that generates the data is fast enough for me right now. The code that generates the animation is significantly slower. Any ideas on how to speed it up? I’m using a scatter plot, but I’d be happy with anything remotely similar that allows me to show particles over time, and allows them to change color.

For extra bonus points, There’s a stacked plot at the top of the animation. I tried to make it animated, and it made the whole thing unbearably slow. I’d love to animate it, but I couldn’t figure out how to do so decently. I’d be happy with anything that showed the trend in a similar way (vlines, etc).

I’m hoping this is an easy question, and I’m definitely aware that I’m no expert with matplotlib animations.

If it helps, I’m quite willing to try out someone else’s recommendation of streamlit.

Thanks!
-Michael

Sorry, don’t have the bandwidth to dive into this right now, but some very quick comments:

  • You are updating the Collection in place so that is already good.
  • The stackplot being slow was likely due to creating a new stackplot everytime
  • There may be a small speed up for using 3 Line2D (what comes back from ax.plot) each of a different color and updating them each time.
  • if you stick with scatter, look into using BoundaryNorm [2] or NoNorm [1] to simplify the color re-mapping
  • blitting only helps if you are working in a desktop GUI with a live kernel
  • turn off (almost) all of the text (the space in the person plot is not meaningful) because drawing text is actually super expensive.
  • make sure you don’t have any rcparams to have tight_layout, constrained_layout, or the bbox_inches='tight' set (would have to check this to be sure, but I think they do trigger during the animation save and will be effectively doubling your render time)

[1] https://matplotlib.org/api/_as_gen/matplotlib.colors.NoNorm.html#matplotlib.colors.NoNorm
[2] https://matplotlib.org/api/_as_gen/matplotlib.colors.BoundaryNorm.html#matplotlib.colors.BoundaryNorm

1 Like

Even if it’s not a full dive, this is definitely helpful. Thanks!

  • I couldn’t figure out how to make an updateable stackplot. Maybe I can get around this with a static one at the beginning, and an animated vline or something.
  • I didn’t realize text was so expensive. That’s awesome to know in general.
  • I probably won’t switch to Line2D since I want to change the number of points for a given color over time … though I suppose I could just cheat (draw too many points every time, with several overlapping)

Thanks!

Line2D has no notion of how many points it has independent of the data you give it. So long as the x and y data are the same length, at draw time it will render the number of points you expect.

1 Like