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

如何在Tkinter中同时运行两个Matplotlib动画?

解决Tkinter中同时运行两个Matplotlib动画的问题

我帮你找出了代码里的几个关键问题,修正后就能同时显示两个动画了,先看修正后的完整代码:

import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.animation as animation
import tkinter as tk

# 提前创建figure和子图,避免每次动画都新建
f = plt.figure(figsize=(6, 2), dpi=100)
ax = f.add_subplot(111)
# 初始化一条空线,后续动画更新数据
line, = ax.plot([], [])
ax.set_xlim(1, 10)
ax.set_ylim(0, 10)

f1 = plt.figure(figsize=(4, 2), dpi=100)
ax1 = f1.add_subplot(111)
line1, = ax1.plot([], [])
ax1.set_xlim(1, 10)
ax1.set_ylim(0, 10)

def animate(i):
    # 这里可以根据i动态生成数据,示例用固定数据演示
    x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    y = [3, 5, 2, 7, 3, 5, 4, 6, 2, 2]
    # 更新线的数据,而不是新建plot
    line.set_data(x, y)
    return line,

def animate1(j):
    x1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    y1 = [6, 1, 4, 9, 4, 2, 5, 1, 2, 4]
    line1.set_data(x1, y1)
    return line1,

class Figure(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.config(background='blue')
        canvas = FigureCanvasTkAgg(f, self)
        canvas.draw()
        canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)

class Figure1(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.config(background='blue')
        canvas = FigureCanvasTkAgg(f1, self)
        canvas.draw()
        canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)

class Calculator(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)  # 修正重复的*kwargs参数
        tk.Tk.wm_title(self, 'Beam calculator')
        container = tk.Frame(self)
        container.pack(side='top', fill='both', expand=True)
        
        bfig = Figure(container, controller=self)
        bfig.grid(row=0, column=0, sticky="nsew")
        # 修正Frame实例化错误,绑定对应的figure f1
        bfig1 = Figure1(container, controller=self)
        bfig1.grid(row=1, column=0, sticky="nsew")

if __name__ == '__main__':
    app = Calculator()
    app.geometry('1280x720')
    # 保留动画对象引用,避免被垃圾回收,启用blit优化动画流畅度
    ani = animation.FuncAnimation(f, animate, interval=1000, blit=True)
    ani1 = animation.FuncAnimation(f1, animate1, interval=1000, blit=True)
    app.mainloop()

关键修改点说明:

  1. 修正Frame实例化错误:
    你之前在Calculator类里把第二个Frame写成了bfig1 = Figure(container, controller=self),这导致两个Frame都绑定了同一个figure f,改成Figure1后才能正确绑定f1,两个figure才会分别显示。

  2. 提前初始化子图和线条:
    原来的animate函数每次都调用add_subplot,会不断创建新的子图,导致旧的子图被覆盖,动画无法正确更新。现在我们提前创建好轴对象(ax、ax1)和空线条(line、line1),在动画函数里只更新线条的数据,效率更高且画面不会混乱。

  3. 修复构造函数参数错误:
    你在Calculator的__init__里写了tk.Tk.__init__(self, *args, *kwargs),这里多了一个*,改成**kwargs才符合语法要求。

  4. 启用blit优化:
    在FuncAnimation里添加blit=True,可以让动画更流畅,它只会更新画面中变化的部分,而非重绘整个画布。

这样修改后,两个Matplotlib动画就能在Tkinter界面里同时正常运行了。

内容的提问来源于stack exchange,提问作者Intoksynator

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:20:20