如何用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
相关产品推荐
相关产品推荐

