Plotting changing arrays
I am trying to plot a re开发者_Go百科al-time signal. I have an array of size 4 that is refreshed every 1/32nd of a second with new data and I need to plot these values for at least 1 sec.
That means, there would be 32 of these arrays of size 4 each. This implies, I will have 32*4 = 128 data points to plot vs the no.of samples(1,2,3....128). How can I go about plotting this in python? I can return the array(of size 4) to a new method and it will do that every 1/32nd of a second, so I have the data coming but don't know how to process it.
Hope I explained my question clearly. I would appreciate any help with this problem.
I like to use wxPython for real time things. Here is an example application that does what you ask. It retrieves generated readings and plots in a window.
(Since I can't see your data, I generate a sine wave in a separate thread and plot it)
import wx
from Queue import Queue, Empty, Full
import threading
from time import sleep
from math import sin
from itertools import count
class Producer(threading.Thread):
def __init__(self,queue):
self.queue=queue
self.t=0
threading.Thread.__init__(self)
self.daemon=False
def run(self):
print "initializing producer"
freq=0.1
secondsBetweenReadings=1.0/32
try:
while True:
readings=[ 256.0*sin(freq*t) for t in range(self.t,self.t+4) ]
self.t = self.t+4
self.queue.put(readings,timeout=0.1)
sleep(secondsBetweenReadings)
except Full:
print "Queue Full. Exiting"
class App(wx.App):
def __init__(self,queue):
self.queue=queue
wx.App.__init__(self,redirect=False)
def OnInit(self):
self.frame=wx.Frame(parent=None,size=(256,256))
self.plotPanel=wx.Panel(self.frame,size=(256,256))
self.plotPanel.SetBackgroundColour(wx.BLACK)
self.data=[]
self.plotPanel.Bind(wx.EVT_PAINT,self.OnPaintPlot)
self.plotPanel.Bind(wx.EVT_ERASE_BACKGROUND,lambda evt: None) #For Windows
self.Bind(wx.EVT_IDLE,self.CheckForData)
self.frame.Show()
return True
def CheckForData(self,evt):
try:
data=self.queue.get(timeout=0.05)
self.data.extend(data)
self.plotPanel.Refresh()
except Empty:
pass
evt.RequestMore()
def OnPaintPlot(self,evt):
w,h=self.plotPanel.GetClientSize()
dc=wx.PaintDC(self.plotPanel)
dc.SetBrush(wx.BLACK_BRUSH)
dc.DrawRectangle(0,0,w,h)
dc.SetPen(wx.WHITE_PEN)
coords=zip(count(),self.data)
if len(coords) > 2:
dc.DrawLines(coords)
if __name__ == "__main__":
maxReadings=32
queue=Queue(maxReadings)
producer=Producer(queue)
plotterApp=App(queue)
producer.start()
plotterApp.MainLoop()
Check out the rtgraph package. It's pretty flexible and should be able to handle this.
精彩评论