用多个图做动画的问题
Problems doing animation with multiple plots
我正在尝试使用 matplotlib 在 4 个不同的子图中制作 4 行动画。但是我只得到了片刻的整个情节,然后情节就空了。
我使用的代码格式与我制作的其他示例类似,没有任何问题。所以我不明白我做错了什么。任何的想法?谢谢
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.animation import FuncAnimation
%matplotlib nbagg
df = pd.read_csv (r"C:\Users\Gaizka\Downloads\V296_220719_38.csv")
t = df.iloc[:,0]
vert = df.iloc[:, 1]
long = df.iloc[:, 2]
tras = df.iloc[:, 3]
sound = df.iloc[:, 4]
x1, y1= [],[]
x2, y2= [],[]
x3, y3= [],[]
x4, y4= [],[]
tdata1, tdata2, tdata3, tdata4 = [], [],[],[]
fig = plt.figure(1, figsize=(10,8))
ax1 = fig.add_subplot(4,1,1)
ax2 = fig.add_subplot(4,1,2)
ax3 = fig.add_subplot(4,1,3)
ax4 = fig.add_subplot(4,1,4)
ax1.grid(True)
ax1.set_ylabel('Vertical Velocity [mm/s]')
ax1.set_xlim (0,8200)
l1, = ax1.plot ([],[],'b-')
ax2.grid(True)
ax2.set_ylabel('Longitudinal Velocity [mm/s]')
ax2.set_xlim (0,8200)
l2, = ax1.plot ([],[],'g-')
ax3.grid(True)
ax3.set_ylabel('Trasversal Velocity [mm/s]')
ax3.set_xlim (0,8200)
l3, = ax1.plot ([],[],'r-')
ax4.grid(True)
ax4.set_xlabel('Time [ms]')
ax4.set_ylabel('Sound [dBl]')
ax4.set_xlim (0,8200)
l4, = ax1.plot ([],[],'k-')
l1, = ax1.plot (t, vert, 'b-')
l2, = ax2.plot (t, long, 'g-')
l3, = ax3.plot (t, tras, 'r-')
l4, = ax4.plot (t, sound, 'k-')
def init():
l1.set_data([],[])
l2.set_data([],[])
l3.set_data([],[])
l4.set_data([],[])
return fig,
def animate(i,l1,l2,l3,l4):
x1.append (tdata1[i])
y1.append (vert[i])
x2.append (tdata2[i])
y2.append (long[i])
x3.append (tdata3[i])
y3.append (tras[i])
x4.append (tdata4[i])
y4.append (sound[i])
l1.set_data(tdata1,vert)
l2.set_data(tdata2,long)
l3.set_data(tdata3,tras)
l4.set_data(tdata4,sound)
return fig,
ani = animation.FuncAnimation(fig, animate, fargs=(l1,l2,l3,l4), frames=len (t), init_func=init, interval=10, blit=True)
plt.show()
您的 init()
和 animate()
函数必须 return 艺术家列表 ,而不是对图形的引用。
你应该有:
def init():
(...)
return (l1,l2,l3,l4)
def animate(i, l1, l2, l3, l4):
(...)
return (l1,l2,l3,l4)
编辑虽然我上面的建议仍然有效,但这实际上不是问题所在。
在您的 animate()
函数中,您引用了一个数组 tdata1[i]
但 tdata1
被初始化为一个空列表,此后从未使用过。因此该函数引发 IndexError
。此外,我不明白为什么要在单独的 x1,y1,...,x4,y4 列表中复制数据框的内容。试试这个:
def animate(i,l1,l2,l3,l4):
l1.set_data(t[:i],vert[:i])
l2.set_data(t[:i],long[:i])
l3.set_data(t[:i],tras[:i])
l4.set_data(t[:i],sound[:i])
return (l1,l2,l3,l4)
一般来说,为了调试动画,我发现手动调用 animate()
很有用。不要创建 FuncAnimation
,而是调用 animate(10, l1, l2, l3, l4)
并查看代码是否引发异常或是否生成预期的图。
我正在尝试使用 matplotlib 在 4 个不同的子图中制作 4 行动画。但是我只得到了片刻的整个情节,然后情节就空了。 我使用的代码格式与我制作的其他示例类似,没有任何问题。所以我不明白我做错了什么。任何的想法?谢谢
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.animation import FuncAnimation
%matplotlib nbagg
df = pd.read_csv (r"C:\Users\Gaizka\Downloads\V296_220719_38.csv")
t = df.iloc[:,0]
vert = df.iloc[:, 1]
long = df.iloc[:, 2]
tras = df.iloc[:, 3]
sound = df.iloc[:, 4]
x1, y1= [],[]
x2, y2= [],[]
x3, y3= [],[]
x4, y4= [],[]
tdata1, tdata2, tdata3, tdata4 = [], [],[],[]
fig = plt.figure(1, figsize=(10,8))
ax1 = fig.add_subplot(4,1,1)
ax2 = fig.add_subplot(4,1,2)
ax3 = fig.add_subplot(4,1,3)
ax4 = fig.add_subplot(4,1,4)
ax1.grid(True)
ax1.set_ylabel('Vertical Velocity [mm/s]')
ax1.set_xlim (0,8200)
l1, = ax1.plot ([],[],'b-')
ax2.grid(True)
ax2.set_ylabel('Longitudinal Velocity [mm/s]')
ax2.set_xlim (0,8200)
l2, = ax1.plot ([],[],'g-')
ax3.grid(True)
ax3.set_ylabel('Trasversal Velocity [mm/s]')
ax3.set_xlim (0,8200)
l3, = ax1.plot ([],[],'r-')
ax4.grid(True)
ax4.set_xlabel('Time [ms]')
ax4.set_ylabel('Sound [dBl]')
ax4.set_xlim (0,8200)
l4, = ax1.plot ([],[],'k-')
l1, = ax1.plot (t, vert, 'b-')
l2, = ax2.plot (t, long, 'g-')
l3, = ax3.plot (t, tras, 'r-')
l4, = ax4.plot (t, sound, 'k-')
def init():
l1.set_data([],[])
l2.set_data([],[])
l3.set_data([],[])
l4.set_data([],[])
return fig,
def animate(i,l1,l2,l3,l4):
x1.append (tdata1[i])
y1.append (vert[i])
x2.append (tdata2[i])
y2.append (long[i])
x3.append (tdata3[i])
y3.append (tras[i])
x4.append (tdata4[i])
y4.append (sound[i])
l1.set_data(tdata1,vert)
l2.set_data(tdata2,long)
l3.set_data(tdata3,tras)
l4.set_data(tdata4,sound)
return fig,
ani = animation.FuncAnimation(fig, animate, fargs=(l1,l2,l3,l4), frames=len (t), init_func=init, interval=10, blit=True)
plt.show()
您的 init()
和 animate()
函数必须 return 艺术家列表 ,而不是对图形的引用。
你应该有:
def init():
(...)
return (l1,l2,l3,l4)
def animate(i, l1, l2, l3, l4):
(...)
return (l1,l2,l3,l4)
编辑虽然我上面的建议仍然有效,但这实际上不是问题所在。
在您的 animate()
函数中,您引用了一个数组 tdata1[i]
但 tdata1
被初始化为一个空列表,此后从未使用过。因此该函数引发 IndexError
。此外,我不明白为什么要在单独的 x1,y1,...,x4,y4 列表中复制数据框的内容。试试这个:
def animate(i,l1,l2,l3,l4):
l1.set_data(t[:i],vert[:i])
l2.set_data(t[:i],long[:i])
l3.set_data(t[:i],tras[:i])
l4.set_data(t[:i],sound[:i])
return (l1,l2,l3,l4)
一般来说,为了调试动画,我发现手动调用 animate()
很有用。不要创建 FuncAnimation
,而是调用 animate(10, l1, l2, l3, l4)
并查看代码是否引发异常或是否生成预期的图。