Python 如何在tkinter中使matplotlib在while循环中设置动画

Python 如何在tkinter中使matplotlib在while循环中设置动画,python,matplotlib,tkinter,Python,Matplotlib,Tkinter,我正试图在tkinter应用程序中实时记录脑电图。但是,当数据在while循环中更新时,它不会打印,而只在最后打印 import tkinter as tk from tkinter import ttk, Button, LabelFrame, N, W, messagebox as box import time import datetime as dt from datetime import date import numpy as np from matplotlib.back

我正试图在tkinter应用程序中实时记录脑电图。但是,当数据在while循环中更新时,它不会打印,而只在最后打印

import tkinter as tk
from tkinter import ttk, Button, LabelFrame, N, W, messagebox as box

import time
import datetime as dt
from datetime import date

import numpy as np

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib
import matplotlib.animation as animation
import matplotlib.pyplot as plt

class NFB_HomePage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        self.nfbprotocol = 0
        self.metricstime = 0
        self.nfbmetric = 0
        self.df = []
        self.xList = []
        self.yList = []

        # Start Neurofeedback
        self.StartNFB = Button(self, text="Start NFB", width=25, command=self.onStartNFB)
        self.StartNFB.grid(row=7, column=0, padx=5, pady=3, sticky=W)

        # LabelFrame for EEG Graph
        labelframe3 = LabelFrame(self, text="EEG Plot")
        labelframe3.grid(row=4, column=2, padx=5, pady=2, sticky=N, rowspan=5, columnspan=4)

        self.fig = plt.Figure(figsize=(10, 5), dpi=100)
        self.ax1 = self.fig.add_subplot(111)
        self.line, = self.ax1.plot([], [], lw=2)
        self.canvas = FigureCanvasTkAgg(self.fig, labelframe3)
        self.canvas.draw()
        self.canvas.get_tk_widget().grid()
        self.canvas._tkcanvas.grid(row=0, column=0, padx=5, pady=3, sticky=W)

    def createDF(self):
        df_timestamp = []
        df_data = np.empty([0, 5])

        # metrics
        df_alpha = np.empty([0, 1])
        df_beta = np.empty([0, 1])
        df_theta = np.empty([0, 1])
        df_delta = np.empty([0, 1])
        df_alpha_theta = np.empty([0, 1])
        df_metricstime = np.empty([0, 1])

        return df_timestamp, df_data, df_alpha, df_beta, df_theta, df_delta, df_alpha_theta, df_metricstime


    def onStartNFB(self):
        try:
            self.start()
            # Initialize dataframes
            df_timestamp, df_data, df_alpha, df_beta, df_theta, df_delta, df_alpha_theta, df_metricstime = self.createDF()

            # Start recording here!
            timestart = time.time()

            while time.time() < timestart + int(4):
                """ 3.1 ACQUIRE DATA """
                self.metricstime = dt.datetime.now().strftime('%H:%M:%S.%f')

                """ 3.3 COMPUTE NEUROFEEDBACK METRICS """
                alpha_metric, beta_metric, theta_metric, delta_metric, alphatheta_metric = float(np.random.normal(size=1)), float(np.random.normal(size=1)), \
                                                                                           float(np.random.normal(size=1)), float(np.random.normal(size=1)), \
                                                                                           float(np.random.normal(size=1))
                self.nfbmetric = alpha_metric

                # Save the bands to data frame
                df_alpha = np.append(df_alpha, [[alpha_metric]], axis=0)
                df_beta = np.append(df_beta, [[beta_metric]], axis=0)
                df_theta = np.append(df_theta, [[theta_metric]], axis=0)
                df_delta = np.append(df_delta, [[delta_metric]], axis=0)
                df_alpha_theta = np.append(df_alpha_theta, [[alphatheta_metric]], axis=0)
                df_metricstime = np.append(df_metricstime, [[self.metricstime]], axis=0)

                # Update graph
                self.df = np.concatenate([df_metricstime, df_alpha, df_theta, df_alpha_theta],
                                         axis=1)
                print(self.nfbmetric)

        except:
            raise RuntimeError("Error with Neurofeedback.")


    def start(self):
        self.ani = animation.FuncAnimation(self.fig, self.animate, interval=int(500))
        self.running = True
        self.ani._start()


    def animate(self,i):
        df = self.df
        for eachline in df:
            if len(eachline) > 1:
                dfX = eachline[0]
                dfY = eachline[1]

                self.xList.append(dfX)
                self.yList.append(dfY)

        self.ax1.clear()
        self.ax1.plot(self.xList, self.yList)
        title = "Neurofeedback Band Power"
        self.ax1.set_title(title)

app = ExpGUI()
app.geometry("1280x720")
app.mainloop()
将tkinter作为tk导入
从tkinter导入ttk、按钮、LabelFrame、N、W、messagebox作为框
导入时间
将日期时间导入为dt
起始日期时间导入日期
将numpy作为np导入
从matplotlib.backends.backend_tkagg导入图CAVASTKAGG
导入matplotlib
将matplotlib.animation导入为动画
将matplotlib.pyplot作为plt导入
NFB_类主页(传统框架):
定义初始化(自、父、控制器):
tk.Frame.\uuuu init\uuuuu(自,父)
self.nfbprotocol=0
self.metricstime=0
self.nfbmetric=0
self.df=[]
self.xList=[]
self.yList=[]
#启动神经反馈
self.StartNFB=按钮(self,text=“Start NFB”,width=25,command=self.onStartNFB)
self.StartNFB.grid(行=7,列=0,padx=5,pady=3,粘性=W)
#脑电图形的LabelFrame
labelframe3=LabelFrame(self,text=“脑电图图”)
labelframe3.grid(行=4,列=2,padx=5,pady=2,粘性=N,行span=5,列span=4)
self.fig=plt.Figure(figsize=(10,5),dpi=100)
self.ax1=self.fig.add_子批次(111)
self.line,=self.ax1.plot([],[],lw=2)
self.canvas=FigureCanvasTkAgg(self.fig,labelframe3)
self.canvas.draw()
self.canvas.get_tk_widget().grid()
self.canvas.\u tkcanvas.grid(行=0,列=0,padx=5,pady=3,粘性=W)
def createDF(自我):
df_时间戳=[]
df_data=np.empty([0,5])
#指标
df_alpha=np.empty([0,1])
df_beta=np.empty([0,1])
df_theta=np.empty([0,1])
df_delta=np.empty([0,1])
df_alpha_theta=np.empty([0,1])
df_metricstime=np.empty([0,1])
返回测向时间戳、测向数据、测向α、测向β、测向θ、测向δ、测向αθ、测向度量时间
def onStartNFB(自):
尝试:
self.start()
#初始化数据帧
df_时间戳、df_数据、df_α、df_β、df_θ、df_δ、df_α、df_θ、df_度量时间=self.createDF()
#从这里开始录音!
timestart=time.time()
而time.time()1:
dfX=eachline[0]
dfY=eachline[1]
self.xList.append(dfX)
self.yList.append(dfY)
self.ax1.clear()
self.ax1.plot(self.xList、self.yList)
title=“神经反馈带电源”
self.ax1.set_标题(标题)
app=ExpGUI()
附录几何(“1280x720”)
app.mainloop()

有人知道我的代码有什么问题吗?我知道如何让它在while循环之外运行,但在数据更新时让它运行有问题。

while
-循环块
mainloop()
,它会重新绘制窗口和所有小部件。您可以使用
app.update()
强制
mainloop
重新绘制窗口。或者使用
app.after(毫秒,函数名称)
定期运行函数(无
while
-loop),并且不阻塞
mainloop()
。读取