如何使用 matplotlib 为多个数组设置动画

How to animate multiple arrays using matplotlib

我正在尝试在数组序列上显示一种绘图刷新。每个数组都是序列的一个实例,我想为每个数组绘制相对数组及其平滑版本,如下所示: these frames should be showed in sequence thanks to the animation function 无论如何,当我 return 来自动画函数的相关行时,会出现以下错误“ AttributeError: 'list' object has no attribute 'get_zorder' ”。我尝试了其他问题和渠道的解决方案,但没有任何效果。这是代码:

import random

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
from scipy.signal import savgol_filter

n_instances = 1000  # the instances that will be generated
instances_duration = 100  # the duration of each of them

# starting the data matrix
process_instances = np.zeros((n_instances, instances_duration))
# starting the filtered data matrix
filtered_instances = np.zeros((n_instances, instances_duration))

np.random.seed(2)
for i in range(n_instances):
    # creating the instance as a random array
    current_instance = np.random.normal(0, 1, instances_duration)
    # assigning to the relative matrix
    process_instances[i, :] = current_instance
    # filtering and assigning to the relative matrix
    filtered_instances[i, :] = savgol_filter(current_instance, 11, 3)

# managing the plots
fig, axs = plt.subplots()
axs.set_ylim([-3, 3])
axs.set_xlim([0, instances_duration])
axs.grid(True)
lines = axs.plot(process_instances[0, :], alpha=0.3, label='original')  # starting the main lines
lines_filt = axs.plot(filtered_instances[0, :], label='filtered')  # starting the filtered lines
axs.legend()


def animate(frame):
    # updating lines
    for columns, line in enumerate(lines):
        line.set_ydata(process_instances[frame, :])
    # updating filtered lines
    for columns, line in enumerate(lines_filt):
        line.set_ydata(filtered_instances[frame, :])
    print("Showing frame number: " + str(frame))
    return [lines, lines_filt]


animation = FuncAnimation(fig, animate, interval=1000, blit=True, repeat=True)
animation.event_source.start()
plt.show()

只需要稍作改动。主要是,您必须为动画循环解压 Line2D 对象

import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
from scipy.signal import savgol_filter

n_instances = 1000  # the instances that will be generated
instances_duration = 100  # the duration of each of them

# starting the data matrix
process_instances = np.zeros((n_instances, instances_duration))
# starting the filtered data matrix
filtered_instances = np.zeros((n_instances, instances_duration))

np.random.seed(2)
for i in range(n_instances):
    # creating the instance as a random array
    current_instance = np.random.normal(0, 1, instances_duration)
    # assigning to the relative matrix
    process_instances[i, :] = current_instance
    # filtering and assigning to the relative matrix
    filtered_instances[i, :] = savgol_filter(current_instance, 11, 3)

# managing the plots
fig, axs = plt.subplots()
axs.set_ylim([-3, 3])
axs.set_xlim([0, instances_duration])
axs.grid(True)
#unpack the Line2D artists
lines, = axs.plot(process_instances[0, :], alpha=0.3, label='original')  # starting the main lines
lines_filt, = axs.plot(filtered_instances[0, :], label='filtered')  # starting the filtered lines
axs.legend()


def animate(frame):
    # updating lines
    lines.set_ydata(process_instances[frame, :])
    # updating filtered lines
    lines_filt.set_ydata(filtered_instances[frame, :])
    print("Showing frame number: " + str(frame))
    
    #return the Line2D artists for blitting
    return lines, lines_filt,


animation = FuncAnimation(fig, animate, interval=1000, blit=True, repeat=True)
animation.event_source.start()
plt.show()