How to generate an animated curve using animation?

I want to generate an animated curve using some certain points. However, when I use the code below, there is no animation showed and the picture’s x-coordinates and y-coordinates keep changing. I use the FuncAnimation function, and the parameter I pass into this function is the plot_gesture, the function that plots all the points.

My trajectory is a list, its elements are all lists(length of 2), it’s like [[2.5,2], [4,3.5], [2,6]….] My position is a ndarray, its elements are all tuples(length of 2), it’s like ((3,5),(6,7)….) The length of trajectory is much longer than that of position, because the position is all the points of the sampled points of the trajectory. The trajectory is all the points of the whole trajectory. So, I need to draw all the points on the trajectory and scatter the points of the position

def plot_gesture(i = int):
X = []
Y = []
X_point = []
Y_point = []

for x in trajectory[:i]:
    X.append(x[0])
    Y.append(x[1])
for x in position[:i]:
    X_point.append(x[0])
    Y_point.append(x[1])
 plt.plot(X, Y)
for x, y in zip(X_point, Y_point):
    plt.scatter(x, y)



if __name__ == "__main__":
trajectory = point_list
position = np.array(sampled_all_points)
ani=animation.FuncAnimation(fig= fig,func= plot_gesture, interval= 20)
plt.show();

Answer

You should always include your data into your question.
Since you haven’t specified what position and trajectory are, I suppose you need a position array with N rows and 2 columns, which contains x and y coordinates for a moving point. I generated an array like this with:

N = 200
time = np.linspace(0, 30, N)
position = np.array([1/3*time*np.cos(time), 1/3*time*np.sin(time)]).T
[[ 0.00000000e+00  0.00000000e+00]
 [ 4.96813143e-02  7.54690426e-03]
 [ 9.59688338e-02  2.98452338e-02]
 [ 1.35597167e-01  6.58794885e-02]
 [ 1.65553654e-01  1.13995649e-01]
 [ 1.83194645e-01  1.71957672e-01]
 [ 1.86350032e-01  2.37024178e-01]
 [ 1.73412613e-01  3.06042995e-01]
 [ 1.43409393e-01  3.75560683e-01]
 [ 9.60523732e-02  4.41943697e-01]
 [ 3.17670638e-02  5.01507457e-01]
...

You need to define a figure to pass to FuncAnimation and an animation function. Within this function you need to:

  • erase previous plot
  • plot current status
  • fix axis in order to avoid unpleasant axes modification during animation

So you can set up the code like this:

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


def animate(i):
    # erase previous plot
    ax.cla()

    # draw point's trajectory
    ax.plot(position[:i + 1, 0], position[:i + 1, 1], linestyle = '-', color = 'blue')

    # draw point's current position
    ax.plot(position[i, 0], position[i, 1], marker = 'o', markerfacecolor = 'red', markeredgecolor = 'red')

    # fix axes limits
    ax.set_xlim(-10, 10)
    ax.set_ylim(-10, 10)


if __name__ == "__main__":
    # position array generation
    N = 200
    time = np.linspace(0, 30, N)
    position = np.array([1/3*time*np.cos(time), 1/3*time*np.sin(time)]).T

    # generate figure and axis
    fig, ax = plt.subplots(figsize = (5, 5))

    # define the animation
    ani = FuncAnimation(fig = fig, func = animate, interval = 20, frames = N)

    # show the animation
    plt.show()

enter image description here