如何用FuncAnimation在同一窗口叠加双摆动画并解决多窗口问题?
解决双摆动画叠加显示与多余空白窗口问题
问题根源
- 动画无法叠加:你的
pendulumAnimation函数每次调用都会新建一个Figure和Axes,完全忽略了传入的ax参数,导致两个动画各自占用独立窗口 - 空白窗口:
animationCall开头创建的fig, ax = plt.subplots()根本没被使用,直接变成了无内容的空白窗口
修改后的完整代码
import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation loc1 = "DoublePendRes1.txt" loc2 = "DoublePendRes2.txt" def calculate_coordinates(L1, L2, angle1, angle2): x1 = L1 * np.sin(angle1) y1 = -L1 * np.cos(angle1) x2 = x1 + L2 * np.sin(angle2) y2 = y1 - L2 * np.cos(angle2) return x1, y1, x2, y2 def pendulumAnimation(timeLst, angle1Lst, angle2Lst, L1, L2, ax, color): # 移除内部新建fig和ax的代码,直接使用传入的ax line, = ax.plot([], [], 'o-', lw=2, color=color) # 修正trail的颜色冲突:去掉硬编码的'r-',用传入的color trail, = ax.plot([], [], alpha=0.6, linewidth=0.8, color=color) trail_x = [] trail_y = [] def init(): line.set_data([], []) trail.set_data([], []) return line, trail def update(frame): angle1 = angle1Lst[frame] angle2 = angle2Lst[frame] x1, y1, x2, y2 = calculate_coordinates(L1, L2, angle1, angle2) line.set_data([0, x1, x2], [0, y1, y2]) trail_x.append(x2) trail_y.append(y2) trail.set_data(trail_x, trail_y) return line, trail # 绑定动画到传入ax所属的figure,而不是新建fig animation = FuncAnimation(ax.figure, update, frames=len(timeLst), interval=10, init_func=init, blit=True) return animation def extract_data(targetFile): dataSet = np.loadtxt(targetFile) timeData = dataSet[:, 0] theta1Set = dataSet[:, 1] theta2Set = dataSet[:, 2] return timeData, theta1Set, theta2Set def animationCall(): # 只创建一次fig和ax,所有动画都用这个ax fig, ax = plt.subplots(figsize=(6, 6)) ax.set_aspect('equal') ax.grid() # 统一设置坐标轴范围,避免重复设置 L_total = 1 + 1 ax.set_xlim(-L_total, L_total) ax.set_ylim(-L_total, L_total) time_evo1, theta1_1, theta2_1 = extract_data(loc1) animation1 = pendulumAnimation(time_evo1, theta1_1, theta2_1, 1, 1, ax, color='blue') time_evo2, theta1_2, theta2_2 = extract_data(loc2) animation2 = pendulumAnimation(time_evo2, theta1_2, theta2_2, 1, 1, ax, color='red') plt.show() animationCall()
关键修改点
- 复用Axes:删除
pendulumAnimation内新建fig和ax的代码,直接使用外部传入的ax,确保所有元素都画在同一个坐标系里 - 绑定正确的Figure:
FuncAnimation的第一个参数改为ax.figure,也就是外部创建的那个唯一的Figure - 修正颜色冲突:原来的trail硬写了
'r-',会覆盖传入的color参数,现在去掉硬编码的颜色,统一用传入的color - 统一坐标轴设置:在
animationCall里一次性设置坐标轴范围,避免重复操作 - 消除空白窗口:现在只创建一次
fig, ax,所有动画都基于这个对象,不会产生多余的空白窗口
数据生成注意事项
如果需要生成两个不同初始条件的数据集,修改数据生成代码的loc和初始条件即可:
# 生成第一个数据集 loc1 = "DoublePendRes1.txt" initCond1 = np.array([np.pi/2, 0, np.pi/2, 0]) doublePendulumCall(initCond1, 1, 1, 1, 1) # 生成第二个数据集(修改初始条件) loc2 = "DoublePendRes2.txt" initCond2 = np.array([np.pi/2, 0, np.pi/2 + 0.01, 0]) # 微小差异展示混沌效应 doublePendulumCall(initCond2, 1, 1, 1, 1)
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

