如何在Tkinter窗口中更新Matplotlib图表而非新建窗口
问题:Tkinter中切换Matplotlib图表出现空白的问题
我希望制作一个可显示Matplotlib图表的Tkinter窗口,无需创建新窗口切换图表。目前我可通过销毁窗口切换,但该方式十分不便。
我的代码如下:
import tkinter as tk from tkinter import * from matplotlib.pyplot import * from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk) from matplotlib.figure import Figure #global variables global stopper data = (([1,2,3,4,5], [1,2,3,4,5]), ([1,2,3,4,5],[5,4,3,2,1])) window = tk.Tk() window.geometry("500x500") def Descision(event): print("go to next dataset") stopper.set(1) for i in data: print(i) frame = Frame(window, width = 750, height = 750) #make a new frame frame.pack() frame.place(anchor='center', relx=0.5, rely=0.5) fig = Figure(figsize = (5, 5), dpi = 100) stopper = IntVar(window, 0) plot1 = fig.add_subplot(111) plot1.plot(i[0], i[1]) canvas = FigureCanvasTkAgg(fig, master = window) canvas.draw() canvas.get_tk_widget().pack() window.bind("<Key>", lambda event : Descision(event)) window.wait_variable(stopper) #wait until user presses a key frame.destroy() #canvas.clear() #"AttributeError: 'FigureCanvasTkAgg' object has no attribute 'clear'"
我想要从data[0]生成的图表切换到data[1]生成的图表,但销毁框架后显示的图表为空白,请问哪里理解有误?
问题原因
- 重复创建组件未清理:每次循环都新建
Figure和Canvas,旧的Canvas组件没有被销毁,会留在窗口中遮挡新图表,导致显示异常。 - Frame逻辑冗余:你创建了Frame但并未将
Canvas放入其中,销毁Frame对Canvas没有影响,旧组件残留引发显示混乱。 - 重复绑定事件:每次循环都执行
window.bind("<Key>", ...),导致事件被多次绑定,触发时可能出现不可预期的行为。
修复方案
复用同一个Figure和Canvas,仅更新图表数据即可,无需反复创建新组件。修改后的代码如下:
import tkinter as tk from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure data = (([1,2,3,4,5], [1,2,3,4,5]), ([1,2,3,4,5],[5,4,3,2,1])) window = tk.Tk() window.geometry("500x500") # 初始化一次Figure、Canvas和Axes fig = Figure(figsize=(5, 5), dpi=100) plot1 = fig.add_subplot(111) canvas = FigureCanvasTkAgg(fig, master=window) canvas.get_tk_widget().pack() current_index = 0 def update_plot(index): # 清除旧图表内容 plot1.clear() # 绘制新数据 x, y = data[index] plot1.plot(x, y) # 刷新Canvas canvas.draw() def switch_dataset(event): global current_index # 切换索引,循环显示 current_index = (current_index + 1) % len(data) update_plot(current_index) print(f"切换到数据集{current_index+1}") # 只绑定一次按键事件 window.bind("<Key>", switch_dataset) # 初始显示第一个数据集 update_plot(current_index) window.mainloop()
修改说明
- 将
Figure、Canvas和Axes(plot1)的初始化移到循环外,只创建一次 - 新增
update_plot函数,负责清除旧图表、绘制新数据并刷新Canvas - 用
current_index跟踪当前显示的数据集,按键时切换索引并更新图表 - 仅绑定一次按键事件,避免重复绑定导致的异常
内容的提问来源于stack exchange,提问作者jabo
相关产品推荐
相关产品推荐

