Matplotlib子图多柱状图动画实现报错求助
解决多子图柱状图动画的AttributeError问题
我明白你遇到的问题了——当用blit=True实现多子图柱状动画时,直接返回BarContainer列表会触发这个错误,因为Matplotlib的blit机制需要操作单个的艺术家对象(比如每个柱子对应的Rectangle),而BarContainer是一组矩形的容器,它本身没有get_zorder方法。
下面是修正后的代码,我会一步步解释改动点:
第一步:正确收集所有柱子的艺术家对象
原来的代码里rects.append(axs[i].bar(...))存的是BarContainer,我们需要把每个容器里的单个矩形都提取出来,这样后续动画更新和blit处理才能正确识别:
import numpy as np from matplotlib import pyplot as plt from matplotlib import animation # 模拟你的3x1000x10数据,这里用3x3x3简化测试 soln = np.array([[[1, 0, 0],[1,1,0],[1, 2, 3]], [[1, 0, 0],[1,1,0],[1, 2, 3]], [[1, 0, 0],[1,1,0],[1, 2, 3]]]) print(soln.shape) fig, axs = plt.subplots(1, 3, figsize=(12, 4)) xs = range(0, soln.shape[2]) # 对应每个柱状图的条数,这里是3 rects = [] # 遍历每个子图,提取所有柱子的Rectangle对象 for i in range(soln.shape[0]): bar_container = axs[i].bar(xs, soln[i, 0, :]) # 把BarContainer里的每个矩形加入rects列表 rects.extend(bar_container)
第二步:修改动画函数,更新所有柱子并返回正确的对象
动画函数需要遍历所有柱子,对应到soln里的位置更新高度,最后返回所有需要更新的艺术家对象(也就是rects这个扁平列表):
def animate(frame): # 遍历每个柱子,计算它属于哪个子图和哪个位置 for idx, rect in enumerate(rects): # 计算子图索引:每个子图有soln.shape[2]个柱子 subplot_idx = idx // soln.shape[2] # 计算该子图内的柱子索引 bar_idx = idx % soln.shape[2] # 更新柱子高度 rect.set_height(soln[subplot_idx, frame, bar_idx]) # 返回所有需要更新的艺术家对象,blit=True需要这个返回值 return rects
第三步:创建并展示动画
最后创建动画时保持blit=True,现在返回的是单个艺术家的列表,就不会触发错误了:
ani = animation.FuncAnimation(fig, animate, frames=soln.shape[1], blit=True, repeat=False) plt.show()
关键改动点总结
- 把
BarContainer里的单个Rectangle对象提取出来,存成扁平的rects列表,而不是存容器本身 - 动画函数更新每个
Rectangle的高度,最后返回这个扁平列表,满足blit=True对返回值的要求 - 计算每个柱子对应的子图和位置时,用整除和取模来映射索引,适配你的
soln数组结构
内容的提问来源于stack exchange,提问作者TIF
相关产品推荐
相关产品推荐

