首页 > 解决方案 > 为什么我的情节没有出现在使用 Tkinter 的 set_data 中?

问题描述

我正在尝试改进我的绘图功能。我想使用plotGraph来自 EEG 板的函数实时绘制数据,从 LSL @ 250Hz 中提取样本。以前,我有一个使用常规的功能版本,每次需要刷新绘图时都会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', fontsize = 9, 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()

标签: pythonperformancematplotlibtkinter

解决方案


您的图表是空的,因为您正在绘制空数组:

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', fontsize = 9, 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([],[], lw=1, 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()

输出:

脑电图


推荐阅读