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

Tkinter嵌入Matplotlib图表无法更新运行问题求助

串口数据实时图表展示问题

我尝试将Arduino通过串口发送的数据展示在图表上,X轴设为程序启动后的时间,Y轴为串口接收的数据。尝试多种方法后效果不佳,调试无报错但代码疑似在update_graphs()函数中卡住。尝试降低Arduino发送速率无效。

更新1:确定为时序问题——VSCode逐行调试正常,自动运行时程序冻结。

更新2:图表仅在VSCode调试暂停再恢复时更新。

初始Python代码

import tkinter as tk
from tkinter import ttk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import serial
import threading
import queue
import time

# 读取串口数据
def read_serial_data(serial_port, data_queue):
    while True:
        try:
            line = serial_port.readline().decode().strip()
            data_queue.put(line)
        except UnicodeDecodeError:
            pass

# 更新图表
def update_graphs():
    start_time = time.time()
    global x_data
    while True:
        try:
            data = data_queue.get_nowait()

            # 计算程序启动后的时间
            current_time = time.time() - start_time

            # 更新数据列表
            x_data.append(current_time)

            # 尝试将数据转为浮点型存入y_data
            try:
                y_data.append(float(data))
            except ValueError:
                print(f"数据转浮点型错误: {data}")
                
            x_data = x_data[-len(y_data):] # 限制列表长度

            ax1.clear()
            ax1.plot(x_data, y_data, label='传感器数据1')
            ax1.set_xlabel('时间(秒)')
            ax1.set_ylabel('传感器数据1')
            ax1.legend()

            canvas.draw()

        except queue.Empty:
            pass
        root.after(100, update_graphs)

# GUI初始化
root = tk.Tk()
root.title("传感器数据图表")

# 串口设置
ser = serial.Serial("COM5", baudrate=9600)

# 线程间通信队列
data_queue = queue.Queue()

# 创建并启动串口读取线程
serial_thread = threading.Thread(target=read_serial_data, args=(ser, data_queue), daemon=True)
serial_thread.start()

# 创建并启动图表更新线程
update_thread = threading.Thread(target=update_graphs, daemon=True)
update_thread.start()

# 创建图表
fig, ax1 = plt.subplots()
x_data, y_data = [], []  # 存储时间和数据的列表

# 将Matplotlib图表嵌入Tkinter窗口
canvas = FigureCanvasTkAgg(fig, master=root)
canvas_widget = canvas.get_tk_widget()
canvas_widget.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

# 启动Tkinter主循环
root.mainloop()

Arduino代码

void setup() {
  
    Serial.begin(9600);

}

void loop() {
  Serial.println(random(0, 50));
  delay(200);
}

更新后的Python代码

import tkinter as tk
from tkinter import ttk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import serial
import threading
import queue
import time

# 读取串口数据
def read_serial_data(serial_port, data_queue):
    while True:
        try:
            line = serial_port.readline().decode().strip()
            data_queue.put(line)
        except UnicodeDecodeError:
            pass

# 更新图表
def update_graphs(start_time):
    while True:
        try:
            data = data_queue.get(timeout=1)

            # 计算程序启动后的时间
            current_time = time.time() - start_time

            # 更新数据列表
            x_data.append(current_time)
            y_data.append(float(data))

            ax1.clear()
            ax1.plot(x_data, y_data, label='传感器数据1')
            ax1.set_xlabel('时间(秒)')
            ax1.set_ylabel('传感器数据1')
            ax1.legend()

            canvas.draw()

        except queue.Empty:
            pass
        except Exception as e:
            print(f"update_graphs函数错误: {e}")

# GUI初始化
root = tk.Tk()
root.title("传感器数据图表")

# 串口设置
ser = serial.Serial("COM5", baudrate=9600)

# 线程间通信队列
data_queue = queue.Queue()

# 创建并启动串口读取线程
serial_thread = threading.Thread(target=read_serial_data, args=(ser, data_queue), daemon=True)
serial_thread.start()

# 创建图表
fig, ax1 = plt.subplots()
x_data, y_data = [], []  # 存储时间和数据的列表

# 将Matplotlib图表嵌入Tkinter窗口
canvas = FigureCanvasTkAgg(fig, master=root)
canvas_widget = canvas.get_tk_widget()
canvas_widget.pack(side=tk.TOP, fill=tk.BOTH, expand=1)

# 获取程序启动时间
start_time = time.time()

# 每200毫秒调度一次图表更新函数
root.after(200, update_graphs, start_time)

# 启动Tkinter主循环
root.mainloop()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 07:32:10