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

如何用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()

关键修改点

  1. 复用Axes:删除pendulumAnimation内新建fig和ax的代码,直接使用外部传入的ax,确保所有元素都画在同一个坐标系里
  2. 绑定正确的Figure:FuncAnimation的第一个参数改为ax.figure,也就是外部创建的那个唯一的Figure
  3. 修正颜色冲突:原来的trail硬写了'r-',会覆盖传入的color参数,现在去掉硬编码的颜色,统一用传入的color
  4. 统一坐标轴设置:在animationCall里一次性设置坐标轴范围,避免重复操作
  5. 消除空白窗口:现在只创建一次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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:02:20