如何在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()
关键修改点说明:
修正Frame实例化错误:
你之前在Calculator类里把第二个Frame写成了bfig1 = Figure(container, controller=self),这导致两个Frame都绑定了同一个figuref,改成Figure1后才能正确绑定f1,两个figure才会分别显示。提前初始化子图和线条:
原来的animate函数每次都调用add_subplot,会不断创建新的子图,导致旧的子图被覆盖,动画无法正确更新。现在我们提前创建好轴对象(ax、ax1)和空线条(line、line1),在动画函数里只更新线条的数据,效率更高且画面不会混乱。修复构造函数参数错误:
你在Calculator的__init__里写了tk.Tk.__init__(self, *args, *kwargs),这里多了一个*,改成**kwargs才符合语法要求。启用blit优化:
在FuncAnimation里添加blit=True,可以让动画更流畅,它只会更新画面中变化的部分,而非重绘整个画布。
这样修改后,两个Matplotlib动画就能在Tkinter界面里同时正常运行了。
内容的提问来源于stack exchange,提问作者Intoksynator
相关产品推荐
相关产品推荐

