You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Matplotlib Animation绘制n条曲线?RuntimeError报错求助

解决Matplotlib Animation绘制多条轨迹的返回值报错问题

需求:使用Matplotlib的animation模块绘制n条健身轨迹(对应GPX文件),1-2条轨迹时功能正常,适配n条轨迹时出现报错。

原代码

import matplotlib.animation as anim
import matplotlib.pyplot as plt
import numpy as np

tracks  = {}
xdata   = {}
ydata   = {}

# 实际场景中n_tracks可能有上百条
n_tracks    = 2
n_waypts    = 100

for ii in range(n_tracks):
    # 生成模拟数据
    lat_pts = np.linspace(10+ii*1,20+ii*1,n_waypts)
    lon_pts = np.linspace(10+ii*1,20+ii*1,n_waypts)

    tracks[str(ii)] = np.array( [lat_pts, lon_pts] )
    xdata[str(ii)]  = []
    ydata[str(ii)]  = []

fig = plt.figure()
ax1 = fig.add_subplot( 1,1,1, aspect='equal', xlim=(0,30), ylim=(0,30) )

plt_tracks  = [ax1.plot([], [], marker=',', linewidth=1)[0] for _ in range(n_tracks)]
plt_lastPos = [ax1.plot([], [], marker='o', linestyle='none')[0] for _ in range(n_tracks)]

def animate(i):
    # 累加轨迹点数据
    for jj in range(n_tracks):
        xdata[str(jj)].append( tracks[str(jj)][0,i] )
        ydata[str(jj)].append( tracks[str(jj)][1,i] )

    # 更新绘图对象数据
    for jj in range(n_tracks):
        plt_tracks[jj].set_data(  xdata[str(jj)][:],  ydata[str(jj)][:] )
        plt_lastPos[jj].set_data( xdata[str(jj)][-1], ydata[str(jj)][-1] )

    return plt_tracks, plt_lastPos

anim    = anim.FuncAnimation( fig, animate, frames=n_waypts, interval=20, blit=True )
plt.show()

报错信息

RuntimeError: The animation function must return a sequence of Artist objects.

解决思路

核心问题是返回值结构不符合要求:当blit=True时,animate函数必须返回一维的Artist对象序列,而原代码返回的是(plt_tracks, plt_lastPos)——两个列表组成的元组,属于嵌套结构,Matplotlib无法正确解析每个独立的Artist对象。

关键修改

将两个列表合并为一个扁平列表返回,替换原return语句:

return plt_tracks + plt_lastPos

额外优化(可选)

原代码用字典存储轨迹数据,对于连续数字索引的场景,改用列表更简洁高效,避免字符串键的冗余操作:

# 替换原字典定义为列表
tracks  = []
xdata   = []
ydata   = []

for ii in range(n_tracks):
    lat_pts = np.linspace(10+ii*1,20+ii*1,n_waypts)
    lon_pts = np.linspace(10+ii*1,20+ii*1,n_waypts)
    tracks.append( np.array( [lat_pts, lon_pts] ) )
    xdata.append( [] )
    ydata.append( [] )

# 修改animate函数中的索引方式
def animate(i):
    for jj in range(n_tracks):
        xdata[jj].append( tracks[jj][0,i] )
        ydata[jj].append( tracks[jj][1,i] )

    for jj in range(n_tracks):
        plt_tracks[jj].set_data( xdata[jj][:], ydata[jj][:] )
        plt_lastPos[jj].set_data( xdata[jj][-1], ydata[jj][-1] )

    return plt_tracks + plt_lastPos

原理说明

blit=True模式下,Matplotlib需要明确获取所有需要重绘的Artist对象(轨迹线、标记点),返回的序列必须是一维的,每个元素对应一个Artist。合并两个列表后,所有轨迹线和标记点会被统一识别为独立的Artist,满足动画重绘的要求。

内容的提问来源于stack exchange,提问作者Alf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 00:31:02