Matplotlib调用FuncAnimation做子图动画报错:缺少必填位置参数curr
报错原因
- 核心问题是你传递动画更新函数的方式错误:
FuncAnimation的第二个参数要求传入函数对象本身,但你写的anim(subplot = subplots[i], dist = dists[i])是直接执行了anim函数,执行时没有传入必须的curr参数,因此直接触发类型错误。 - 之前单张子图的场景你是直接传入函数名
anim(没有加括号执行),FuncAnimation会自动把当前帧数值作为第一个参数传给anim,所以不会报错。如果需要给更新函数传递除帧参数外的其他自定义参数,需要使用FuncAnimation的fargs参数传入参数元组,不能直接在函数名后加括号传参。
其他隐含问题
- 你定义的
anim函数中使用了未声明的变量p1、p2、step,需要替换为你预先定义好的对应子图的bins参数 - 循环只遍历了
range(3),会漏掉第4个子图 - 循环中每次覆盖变量
a会导致前面的动画对象被Python垃圾回收,动画无法正常运行,需要将所有动画对象存入列表留存 anim函数中直接调用a.event_source.stop()会因为a是循环最后赋值的对象,导致无法正确停止对应动画
修正后可运行的参考代码
import matplotlib import matplotlib.animation as animation import numpy as np import matplotlib.pyplot as plt # 创建画布和网格子图 fig = plt.figure(figsize=(10,8)) gspec = matplotlib.gridspec.GridSpec(6,6) top_left = plt.subplot(gspec[0:2,0:3]) top_right = plt.subplot(gspec[0:2,3:], sharey = top_left) bottom_left = plt.subplot(gspec[3:5,0:3], sharey = top_left) bottom_right = plt.subplot(gspec[3:5,3:], sharey = top_left) # 生成随机分布数据 x1 = np.random.normal(-2.5, 1, 10000) x2 = np.random.gamma(2, 1.5, 10000) x3 = np.random.exponential(2, 10000)+7 x4 = np.random.uniform(14,20, 10000) n = 10000 # 动画更新函数 def anim(curr, subplot, dist, bins): if curr >= 100: subplot.cla() subplot.hist(dist[:curr], bins=bins) subplot.set_ylabel('Frequency') subplot.set_xlabel('Value') subplot.annotate(f'n={curr}', xy=(0.7, 0.9), xycoords='axes fraction') if curr == n-1: plt.gcf().canvas.stop_event_loop() subplots = [top_left, top_right, bottom_left, bottom_right] bins = [np.arange(-6,2,0.5),np.arange(-1,15,0.5), np.arange(5,20,0.5), np.arange(13.5,20.5,0.5)] dists = [x1,x2,x3,x4] # 存储动画对象避免被回收 anims = [] for i in range(4): a = animation.FuncAnimation( fig, anim, fargs=(subplots[i], dists[i], bins[i]), frames=n, interval=20, repeat=False ) anims.append(a) plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者Mauro
相关产品推荐
相关产品推荐

