在Tkinter GUI上嵌入matplotlib图表

3

Embedding matplotlib graph of Tkinter GUI大家晚上好... 我正在学习如何在Tkinter GUI中嵌入matplotlib图形,但是我没有成功,我附上了一张图片,以展示正在发生的情况,请帮助我。

我从Arduino串口获取数据(心电图读数),并用matplotlib将其绘制(嵌入到Tkinter GUI中),但是当我运行下面的代码时,会创建一个matplotlib图,其中正在进行绘制。

请注意,我的目标是直接在GUI上的图形上绘制图案,不要担心已经绘制的图形。

[![enter image description here][1]][1]import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure
import numpy as np
import serial as sr
import time


def start_plot():
    data = np.array([])
    while True:
        a = s.readline()
        a.decode()
        b = float(a[0:4])
        data = np.append(data, b);
        plt.cla()
        plt.plot(data)
        plt.pause(0.01)
    s.close()

main_window = Tk()
main_window.configure(background='light blue')
main_window.iconbitmap('lardmon_icon.ico')
main_window.title("ECG-LArdmon")
main_window.geometry('800x700')
main_window.resizable(width=False, height=False)




plotting_frame = LabelFrame(main_window, text='Real Time', bg='white', width=300, height=440, bd=5, relief=SUNKEN)
controls_frame = LabelFrame(main_window, text='Controls', background='light grey', height=150)

controls_frame.pack(fill='both', expand='1', side=TOP, padx=20, pady=10)
plotting_frame.pack(fill='both', expand='yes', side=BOTTOM, padx=20)


start_button = Button(controls_frame, text='Start Monitoring', width=16, height=2, borderwidth=3, command=start_plot)
start_button.pack(side=LEFT, padx=26)

exit_button = Button(controls_frame, text='Close', width=10, height=2, borderwidth=3, command=main_window.destroy)
exit_button.pack(side=RIGHT, padx=26)



s = sr.Serial('COM3', 9600)
fig = Figure()
ax = fig.add_subplot(111)
ax.set_title("Electrocadiogram")
ax.set_xlabel("Time(Sec)")
ax.set_ylabel("Voltage(mV)")
ax.set_xlim(0, 200)
ax.set_ylim(-0.5, 6)
ax.grid(b=True, which='major', color='#666666', linestyle='-')
ax.minorticks_on()
ax.grid(b=True, which='minor', color='#666666', linestyle='-', alpha=0.2)
canvas = FigureCanvasTkAgg(fig, master=plotting_frame)
canvas.get_tk_widget().place(x = 0, y = 0, width = 600, height = 420)
canvas.draw()

main_window.mainloop()

1
原因很简单:您的函数没有在您已经创建的“Figure”和“ax”上绘图。相反,您正在调用“plt.plot”,这将创建一个新实例并在单独的线程上运行。还要注意,“while”循环会冻结您的GUI界面。 - Henry Yik
@HenryYik,这就是我感到困惑的地方,我该如何解决它? - Kennerdol
1个回答

2
  1. 你已经创建了一个 Figure 对象和一个 ax,所以总是在它上面绘制并更新你的 canvas
  2. 使用 tkinter.after 方法递归调用你的函数,这样它就不会冻结你的GUI。

下面是最小的更改,以展示如何实现:

import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure
import numpy as np

from tkinter import *

data = []

def start_plot():
    data.append(np.random.uniform(0, 5))
    ax.plot(data, color="blue")
    canvas.draw_idle()
    main_window.after(100, start_plot) # in milliseconds, 1000 for 1 second

# no change to the rest
....

感谢兄弟的帮助,你真的救了我的命,祝福一路相伴。 - Kennerdol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接