0

I am trying to create an animation containing a fixed sphere and a trajectory on the surface of the sphere, with a trail of the trajectory containing the last "windowSize" points in the trajectory.

Now, for the purposes of the code I will show here, I won't have an actual such trajectory, but rather just some random points changing each frame.

I am using matplotlib.animation.FuncAnimation. When I use the option blit=False, the animation works as expected. However, I would like to use blit=True to optimize performance.

When I do that, though, what happens is that nothing seems to happen in the animation, except that when I rotate the figure, then it shows an updated version of the figure (some number of frames ahead) and then freezes again.

The code below is based on this similar question.

Let me show the code I am using

import numpy as np
from matplotlib import pyplot as plt
import matplotlib.animation
import pandas as pd

Np = 5000
windowSize = 1000

m = np.random.rand(Np, 3)

df = pd.DataFrame({ "x" : m[0:Np,0], "y" : m[0:Np,1], "z" : m[0:Np,2]})

def init_graph():
    u, v = np.mgrid[0:2*np.pi:50j, 0:np.pi:50j]
    x = np.cos(u)*np.sin(v)
    y = np.sin(u)*np.sin(v)
    z = np.cos(v)
    ax.plot_surface(x, y, z, color="bisque", alpha=0.3)
    return graph,

def update_graph(num):
    if (num<windowSize):
        graph._offsets3d = (df.x[0:num], df.y[0:num], df.z[0:num])
    else:    
        graph._offsets3d = (df.x[(num-windowSize):num], df.y[(num-windowSize):num], df.z[(num-windowSize):num])
    
    title.set_text('3D Test, time={}'.format(num))
    return graph,

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.set_box_aspect((1,1,1))
title = ax.set_title('3D Test')

graph = ax.scatter(0, 0, 0)

ani = matplotlib.animation.FuncAnimation(fig, update_graph, frames=Np, init_func=init_graph, interval=200, blit=True, repeat=False)

plt.show()

m is an Np by 3 matrix, and each row represents a 3d point (in my real use case, each row is a point in a trajectory on the sphere surface, but for this demo I created m as random numbers).

I create a variable graph that contains a scatter plot, which I believe is an Artist. This is what I return from both the init_func and the updating func which are passed to FuncAnimation (as per the docs).

From what I read, you return an iterable of the Artists which will be updated in the animation. Thus I return a tuple of one element, graph,.

Now, in update_graph, the updating function for the animation, I am updating the scatter plot using graph._offsets3d, which I read in another question here on StackOverflow. I am not totally sure if this is the way to do it and I didn't find much information in the docs about whether to use this or one of the setting methods on the scatter plot.

Why doesn't blitting work with scatter plots?

evianpring
  • 3,316
  • 1
  • 25
  • 54

0 Answers0