I'm trying to live plot EEG recording in my tkinter app. However, it does not plot while the data is updating in the while loop, and plots only at the end.
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()
Does somebody know what is wrong with my code? I know how to get it to run outside the while loop, but I have problems getting it to run while the data is updating.