c.wen
c.wen

Reputation: 35

matplotlib animated line plot stays empty

I am trying to follow the basic animation tutorial located here and adapting it to display an already computed dataset instead of evaluating a function every frame, but am getting stuck. My dataset involves XY coordinates over time, contained in the lists satxpos and satypos I am trying to create an animation such that it traces a line starting at the beginning of the dataset through the end, displaying say 1 new point every 0.1 seconds. Any help with where I'm going wrong?

from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np

Code here creates satxpos and satypos as lists

fig = plt.figure()
ax = plt.axes(xlim=(-1e7,1e7), ylim = (-1e7,1e7))
line, = ax.plot([], [], lw=2)

def init():
    line.set_data([], [])
    return line,

def animate(i):
    line.set_data(satxpos[i], satypos[i])
    return line,

anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames = len(satxpos), interval = 1, blit=True)

Edit: The code runs without errors, but generates a blank plot window with no points/lines displayed and nothing animates. The dataset is generated correctly and views fine in a static plot.

Upvotes: 1

Views: 1734

Answers (3)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339340

In order to "trace a line starting at the beginning of the dataset through the end" you would index your arrays to contain one more element per timestep:

line.set_data(satxpos[:i], satypos[:i])

(Note the :!)

Everything else in the code looks fine, such that with the above manipulation you should get and extending line plot. You might then want to set interval to something greater than 1, as that would mean 1 millesecond timesteps (which might be a bit too fast). I guess using interval = 40 might be a good start.

Upvotes: 4

Y. Luo
Y. Luo

Reputation: 5732

I saw you mentioned "the parts that generate satxpos and satypos do create valid datasets. I can view those as a static plot just fine". But my guess is still the problem originated from your satxpos and satypos.

One way you can trouble shoot is to replace your two functions and animation code with line.set_data(satxpos[i], satypos[i]). Set i as 0, 1, ... and see if you can see the plot. If not, your satxpos and satypos are not as valid as you claimed.

As an example, a valid satxpos and satypos can be like this:

x = np.array([np.linspace(-1e7, 1e7, 1000)])
i = 200
satxpos = x.repeat(i, axis=0)
satypos = np.sin(2 * np.pi * (satxpos - 0.01 * np.arange(i).reshape(-1, 1).repeat(satxpos.shape[1], axis=1)))
satypos *= 1e7 / 2

This works with the code you provided thus indicating the code you've shown us is fine.

Edit in response to comments:

If your satxpos and satypos are just np.linespace, the animation loop will get just one point with (satxpos[i], satypos[i]) and you won't see the point on the plot without a setting like marker='o'. Therefore, you see nothing in your animation.

Upvotes: 1

cosinepenguin
cosinepenguin

Reputation: 1575

Your code looks correct! So long as satxpos and satypos are both configured and initialized properly, I believe everything else is valid!

One part of the code you do not show in your question is the invocation of the anim.save() and plt.show() functions, which are both necessary for your code to work (as per the tutorial you shared!)

You would therefore need to add something like:

anim.save('basic_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264'])

plt.show()

to the end of your code to create the animation (and show it, I presume)!

Hope it helps!

Source - Matplotlib Animation Tutorial

Upvotes: 1

Related Questions