开发者

Plotting changing arrays

开发者 https://www.devze.com 2023-03-28 09:44 出处:网络
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.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消