问题描述
我正在尝试改善绘图功能。我想使用我的plotGraph
函数以实时的方式从EEG板上绘制数据,从250Hz的LSL提取样本。以前,我有一个使用常规self.ax.plot(x,y)
的功能版本,每次需要刷新绘图时都使用self.ax.clear()
清除数据。尽管如此,一些分析表明,与其余代码相比,我的代码花了太多时间进行绘制。
我得到的建议之一是使用set_data
代替绘图和清除。我想同时绘制多行数据,因此我尝试遵循Matplotlib multiple animate multiple lines,您可以在下面看到(适应的代码)。另外,还告诉我使用尝试过的self.figure.canvas.draw_idle()
,但不确定是否正确完成了操作。
不幸的是,它没有用,图形没有更新,我似乎也找不到原因。我知道我刚刚提到的来源使用animation.FuncAnimation
,但是我不确定这是问题所在。是吗?
为什么我的线条都没有显示在画布的图形中?
import tkinter as tk
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import figureCanvasTkAgg
import numpy as np
class AppWindow:
def plotGraph(self,x,y):
for lnum,line in enumerate(self.lines):
line.set_data(x[:],y[:,lnum])
self.figure.canvas.draw_idle()
plt.ylabel('Magnitude',fontsize = 9,color = tx_color)
plt.xlabel('Freq',color = tx_color)
self.figure.canvas.draw()
def __init__(self):
self.root = tk.Tk() #start of application
self.canvas = tk.Canvas(self.root,height = 420,width = 780,bg =
bg_color,highlightthickness=0)
self.canvas.pack(fill = 'both',expand = True)
self.figure = plt.figure(figsize = (5,6),dpi = 100)
self.figure.patch.set_facecolor(sc_color)
self.ax = self.figure.add_subplot(111)
self.ax.clear()
self.line,= self.ax.plot([],[],lw=1,color = tx_color)
self.line.set_data([],[])
#place graph
self.chart_type = figureCanvasTkAgg(self.figure,self.canvas)
self.chart_type.get_tk_widget().pack()
self.lines = []
numchan = 8 #let's say I have 8 channels
for index in range(numchan):
lobj = self.ax.plot([],lw=2,color=tx_color)[0]
self.lines.append(lobj)
for line in self.lines:
line.set_data([],[])
def start(self):
self.root.mainloop()
解决方法
您的图表为空,因为您正在绘制空数组:
line.set_data([],[])
如果填写线阵列,则图表可以正确绘制。
尝试此代码。它将每秒用新的随机数据更新图表。
import tkinter as tk
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import numpy as np
import random
bg_color='grey'
tx_color='green'
sc_color='linen'
numchan = 8
chlen = 100
xvals=[(x-40)/20 for x in range(chlen)] # X coordinates
chcolors= ['gold','blue','green','maroon','red','brown','purple','cyan']
class AppWindow:
def plotGraph(self):
self.figure.canvas.draw_idle()
plt.ylabel('Magnitude',fontsize = 9,color = tx_color)
plt.xlabel('Freq',color = tx_color)
self.figure.canvas.draw()
def UpdateChannelData(self): # callback with new data
# fake random data
for i,ch in enumerate(self.chdata):
for p in range(len(ch)):
ch[p] += (random.random()-.5)/100
self.lines[i].set_data(xvals,ch)
self.plotGraph()
self.root.after(100,self.UpdateChannelData) # simulate next call
def __init__(self):
global chzero
self.root = tk.Tk() #start of application
self.canvas = tk.Canvas(self.root,height = 420,width = 780,bg = bg_color,highlightthickness=0)
self.canvas.pack(fill = 'both',expand = True)
self.figure = plt.figure(figsize = (5,6),dpi = 100)
self.figure.patch.set_facecolor(sc_color)
self.ax = self.figure.add_subplot(111)
self.ax.clear()
self.line,= self.ax.plot([],[],lw=1,color = tx_color)
self.line.set_data([],[])
#place graph
self.chart_type = FigureCanvasTkAgg(self.figure,self.canvas)
self.chart_type.get_tk_widget().pack()
self.lines = []
#numchan = 8 #let's say I have 8 channels
for index in range(numchan):
lobj = self.ax.plot([],color=chcolors[index])[0]
self.lines.append(lobj)
# set flat data
self.chdata = [[0 for x in range(chlen)] for ch in range(numchan)]
self.root.after(1000,self.UpdateChannelData) # start data read
def start(self):
self.root.mainloop()
AppWindow().start()
输出: