7

I have been researching on how to animate multiple lines for a flight path. The object it that I read multiple GPS files time sync them them animate each path with respect to time. I found how to animate one line using append in the animate functions. Now I need to add a second and third for as many files are imported.

I know the problem is somewhere in how I perform the set_data with the lines. I ahve seen multiple example but I do not understand what structure is required to set up multiple lines. Yes I am a newbie.

fig = plt.figure()
ax1 = plt.axes(xlim=(-108, -104), ylim=(31,34))
line, = ax1.plot([], [], lw=2)
plt.xlabel('Longitude')
plt.ylabel('Latitude')



plotlays, plotcols = [2], ["black","red"]
lines = []
for index in range(2):
    lobj = ax1.plot([],[],lw=2,color=plotcols[index])[0]
    lines.append(lobj)


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

x1,y1 = [],[]
x2,y2 = [],[]

frame_num = len(gps_data[0])

# animation function.  This is called sequentially
def animate(i):

    x = gps_data[0][i,3]
    y = gps_data[0][i,2]
    x1.append(x)
    y1.append(y)

    x = gps_data[1][i,3]
    y = gps_data[1][i,2]
    x2.append(x)
    y2.append(y)

    #X = np.array(x1, x2)
    #Y = np.array(y1, y2)

    #for index in range(0,1):
    for lnum,line in enumerate(lines):
        line.set_data([x1,y1, x2,y2])
    return lines,


# call the animator.  blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=frame_num, interval=1, blit=True)


plt.show()
user18472
  • 71
  • 1
  • 1
  • 2

2 Answers2

10

The Matplotlib documentation for the line2d artist explains how set_data works. It "ACCEPTS: 2D array (rows are x, y) or two 1D arrays." It also works with lists. You've given it a four element list instead. You need to set the x and y data of each line separately. I've included an example with fake data below.

import matplotlib.pyplot as plt
from matplotlib import animation
from numpy import random 

fig = plt.figure()
ax1 = plt.axes(xlim=(-108, -104), ylim=(31,34))
line, = ax1.plot([], [], lw=2)
plt.xlabel('Longitude')
plt.ylabel('Latitude')

plotlays, plotcols = [2], ["black","red"]
lines = []
for index in range(2):
    lobj = ax1.plot([],[],lw=2,color=plotcols[index])[0]
    lines.append(lobj)


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

x1,y1 = [],[]
x2,y2 = [],[]

# fake data
frame_num = 100
gps_data = [-104 - (4 * random.rand(2, frame_num)), 31 + (3 * random.rand(2, frame_num))]


def animate(i):

    x = gps_data[0][0, i]
    y = gps_data[1][0, i]
    x1.append(x)
    y1.append(y)

    x = gps_data[0][1,i]
    y = gps_data[1][1,i]
    x2.append(x)
    y2.append(y)

    xlist = [x1, x2]
    ylist = [y1, y2]

    #for index in range(0,1):
    for lnum,line in enumerate(lines):
        line.set_data(xlist[lnum], ylist[lnum]) # set data for each line separately. 

    return lines

# call the animator.  blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
                               frames=frame_num, interval=10, blit=True)


plt.show()
Molly
  • 13,240
  • 4
  • 44
  • 45
  • 1
    Thank you! I used your code to plot a time series. But I had to remove `blit=True`, because it kept the values on the x-axis from being updated. – Elias Strehle Mar 19 '18 at 17:30
  • @Molly, how to add legend based on the plotcols defined in the code ? – Mari Aug 22 '19 at 08:33
  • I got error: x = gps_data[0][0, i] TypeError: 'int' object is not subscriptable – djsg Sep 15 '20 at 05:12
1
fig, ax1 = plt.subplots(figsize=(20,10))

plt.xticks()
ax1.set_xlabel("time")
ax1.set_ylabel("amp")
ax1.grid(True)

ox = get_data_o("/tmp/bf_ox.npy")
oy = get_data_o("/tmp/bf_oy.npy")

graphic_data = []

graphic_data.append(ax1.plot(ox, oy,"b-")[0])

sx = get_data_o("/tmp/bf_sx.npy")

i = 1
for p in sp.procs:
    c = get_c(i)
    sy = get_data_o("/tmp/bf_" + p + ".npy")
    graphic_data.append(ax1.plot(sx, sy,c + "-")[0])
    i = i + 1

def animate(i):
    print ("frame")
    ox = get_data_o("/tmp/bf_ox.npy")
    oy = get_data_o("/tmp/bf_oy.npy")
    i = 0
    graphic_data[i].set_xdata(ox)
    graphic_data[i].set_ydata(oy)
    i = 1
    sx = get_data_o("/tmp/bf_sx.npy")
    for p in sp.procs:
        sy = get_data_o("/tmp/bf_" + p + ".npy")
        graphic_data[i].set_xdata(sx)
        graphic_data[i].set_ydata(sy)
        i = i + 1
        
    return graphic_data
    
ani = animation.FuncAnimation(fig, animate, interval=2000, blit=True)
plt.show()
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 02 '22 at 04:38