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

如何使用Matplotlib和Tkinter实现5秒后更新完整图表?

解决定时更新Tkinter中Matplotlib图表的问题

问题回顾

  • 代码预期功能:调用get_latest_data(1)绘制初始数据,5秒后调用get_latest_data(2)重绘更新数据
  • 代码现有功能:仅能完成首次图表绘制,无法触发后续更新

原代码的核心问题

  • 线程调用参数不匹配:启动线程时传递了队列,但get_latest_data需要的是dataid参数
  • 缺少定时触发逻辑:没有实现5秒后调用更新函数的机制
  • 变量作用域错误:display_result和get_result无法访问UI类内部的图表对象(如a、canvas)
  • 重绘逻辑缺失:更新时未清除旧图表,直接绘制会导致数据叠加

修复后的完整代码

from threading import Thread
from queue import Empty, Queue
import time
import tkinter as tk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure

class tkChartGUI(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.parent = parent
        self.result_queue = Queue()
        self.canvas = None
        self.ax = None
        self.initUI()
        # 5秒后触发更新数据
        self.parent.after(5000, self.update_chart)

    def get_latest_data(self, dataid):
        x_array=[]
        y_array=[]
        if (dataid == 1):
            x_array=[1,2,3,4,5,6,7,8,9,10,11,12,13,14]
            y_array=[0.5,0.7,0.3,1.0,0.6,0.9,0.5,0.2,0.1,0.5,0.33,0.55,0.3,0.6]
        if (dataid == 2):
            x_array=[1,2,3,4,5,6,7,8,9,10,11,12,13,14]
            y_array=[0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.1,1.2,1.3]
        return (x_array, y_array)

    def initUI(self):
        self.parent.title("Simple chart")
        self.parent.geometry("800x600+300+100")
        
        # 绘制初始图表
        x_array, y_array = self.get_latest_data(1)
        f = Figure(figsize=(5, 3), dpi=150)
        self.ax = f.add_subplot(111)
        self.ax.set_xlabel("Values_X")
        self.ax.set_ylabel("Values_Y")
        self.ax.yaxis.grid(True, which='major')
        self.ax.xaxis.grid(True, which='major')
        self.ax.plot(x_array, y_array)
        
        self.canvas = FigureCanvasTkAgg(f, master=self.parent)
        self.canvas.draw()
        self.canvas.get_tk_widget().grid(row=0,column=0)

    def update_chart(self):
        # 用线程获取新数据(避免阻塞UI)
        Thread(target=self.get_result, args=[2], daemon=True).start()
        # 检查队列中的数据并更新图表
        self.display_result()

    def get_result(self, dataid):
        x_array, y_array = self.get_latest_data(dataid)
        self.result_queue.put(x_array)
        self.result_queue.put(y_array)

    def display_result(self):
        x_array = []
        y_array = []
        try:
            x_array = self.result_queue.get(block=False)
            y_array = self.result_queue.get(block=False)
        except Empty:
            # 如果队列还没数据,100ms后再检查
            self.parent.after(100, self.display_result)
            return
        
        # 清除旧图表,绘制新数据
        self.ax.clear()
        self.ax.set_xlabel("Values_X")
        self.ax.set_ylabel("Values_Y")
        self.ax.yaxis.grid(True, which='major')
        self.ax.xaxis.grid(True, which='major')
        self.ax.plot(x_array, y_array)
        self.canvas.draw()

    def onExit(self):
        self.quit()

def main():
    root = tk.Tk()
    my_gui = tkChartGUI(root)
    root.mainloop()

if __name__ == '__main__':
    main()

关键修改说明

  • 将队列、画布、坐标轴对象设为类的属性,让所有方法都能访问
  • 在__init__中用after(5000, self.update_chart)实现5秒后触发更新
  • 新增update_chart方法,负责启动线程获取新数据并触发显示逻辑
  • display_result方法中加入队列空时的重试逻辑,确保能获取到线程返回的数据
  • 更新图表前先调用self.ax.clear()清除旧内容,避免数据叠加
  • 修正线程调用的参数,确保get_result能正确传递dataid

当前代码运行效果

当前代码运行效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:41:18