2009-07-25 20 views
2

シリアルポートから連続したデータを読み込むためのGUIを開発しています。データを読み取った後、計算が行われ、結果がプロットされ、リフレッシュされます(ダイナミックプロッティングとも呼ばれます)。私はこの目的のためにmatplotlibで提供されているwxバックエンドを使用します。これを行うためには、基本的に配列を使用して結果を保存します。各計算の後にそれを追加し続け、グラフ全体を再配置します。それを「動的」にするために、各繰り返しに対してx軸の下限と上限を設定するだけです。見られるような何かを:wxpythonの動的プロット

http://eli.thegreenplace.net/2008/08/01/matplotlib-with-wxpython-guis/

問題、しかし、データが連続しているので、私はそれをプロットし続ければ、そして、最終的にシステムメモリが不足しますと、システムがクラッシュするということです。私の結果を継続的にプロットできる他の方法はありますか?これを行うには

答えて

3

、私は基本的に私は、古いデータを削除するかのいずれかによって、この配列のサイズを制限してみ

にそれを追加 を維持する私の結果を格納する配列 を使用すべてのn番目のエントリを削除します(画面解像度によって、すべてのエントリが表示されなくなります)。私はあなたが何かを失うことはありませんので、ディスクにすべてのデータを書き込むと仮定します。

また、メモリリークのコードを分析してください。あなたが使っているものはもう必要ではありませんが、それでも参照があるのでガベージコレクションされません。

+0

。配列のサイズを削除/制限します。あなたは正しいです、プロットのほかに、データはディスクのファイルに保存されます。それでも可能であれば、ユーザーはプロットの全体または特定の範囲を見ることができる機能を作成したいと思います(x軸の制限を設定する動的プロットに加えて)。 – teonghan

1

私はニシキヘビTkinterので、そのようなコンポーネントを作成しました。ソースはhereです。

基本的には、プロットされたデータはどこかでのままにしておく必要があります。無限のデータポイントをメモリに保存することはできないため、ディスクに保存するか古いデータポイントを上書きする必要があります。

+0

ええ、私は同意する、無限ループ/追加は災害です。コードを共有してくれてありがとう、それを見てみましょう。 – teonghan

1

データとデータの表現は、2つの異なるものです。後で分析する重要なデータであれば、データをディスクに保存することができますが、一定の期間または表示のために最後のNポイントを保持するだけです。ユーザーは、表示される時間枠を選択させることさえできます。

+0

多分このような何か? 1.動的プロット:固定xレンジで、未使用の値を削除して配列のサイズを制限します。 2.すべてのデータがディスク内のファイルに書き込まれています 3.ユーザ定義のプロット:以前にディスクに保存されたデータを読み込み、それをプロットします – teonghan

+0

そのようなものです。ポイント1では、おそらく「未使用」ではなく「最も古い」を意味します:) – Mathieu

0

私は実際に(...実際には、精神的なブロックのより)この問題に遭遇しました。すべての

まず私はコピー&ペーストwx Demo CodeからいくつかのWXプロットコードを。

私が行うことは、値のライブログを保持し、それを2つのマーカー(最小と最大、赤と緑の点線で示されている)と比較することです(ただし、これらの2つのマーカーはオプションです - 。

ライブログを実装するには、デューククラスを最初に使用したかったのですが、データがタプルモード(x、y座標)になっているので、私はあきらめてタプルのパラメータリスト全体を書き直そうとしました。 _update_coordinatesを参照してください。

それは最後の100〜10,000のプロットを追跡するためだけで正常に動作します。また、PrintScreenを含まが、私は許可するのStackOverflowでのnoobのあまりてるだろう:))

私のライブパラメータが115kbpsと高速のUART上で0.25秒ごとに更新されます。

トリックは、カスタムリフレッシュ方法では、最後にあります!ここで

は、コードの中で最もです:私は同じようなことを考えている

class DefaultPlotFrame(wx.Frame): 
    def __init__(self, ymin=0, ymax=MAXIMUM_PLOTS, minThreshold=None, 
      maxThreshold=None, plotColour='blue', 
      title="Default Plot Frame", 
      position=(10,10), 
      backgroundColour="yellow", frameSize=(400,300)): 

     self.minThreshold = minThreshold 
     self.maxThreshold = maxThreshold 
     self.frame1 = wx.Frame(None, title="wx.lib.plot", id=-1, size=(410, 340), pos=position) 
     self.panel1 = wx.Panel(self.frame1) 
     self.panel1.SetBackgroundColour(backgroundColour) 
     self.ymin = ymin 
     self.ymax = ymax 
     self.title = title 
     self.plotColour = plotColour 

     self.lines = [None, None, None]     

     # mild difference between wxPython26 and wxPython28   
     if wx.VERSION[1] < 7: 
      self.plotter = plot.PlotCanvas(self.panel1, size=frameSize) 
     else: 
      self.plotter = plot.PlotCanvas(self.panel1) 
     self.plotter.SetInitialSize(size=frameSize) 
     # enable the zoom feature (drag a box around area of interest) 
     self.plotter.SetEnableZoom(False) 

     # list of (x,y) data point tuples   
     self.coordinates = [] 
     for x_item in range(MAXIMUM_PLOTS): 
      self.coordinates.append((x_item, (ymin+ymax)/2)) 

     self.queue = deque(self.coordinates)    

     if self.maxThreshold!=None:    
      self._update_max_threshold()    
     #endif   

     if self.lockThreshold!=None:    
      self._update_min_threshold()    
     #endif 

     self.line = plot.PolyLine(self.coordinates, colour=plotColour, width=1)     
     self.lines[0] = (self.line)              

     self.gc = plot.PlotGraphics(self.lines, title, 'Time', 'Value') 
     self.plotter.Draw(self.gc, xAxis=(0, MAXIMUM_PLOTS), yAxis=(ymin, ymax))    

     self.frame1.Show(True) 

    def _update_max_threshold(self): 
     if self.maxThreshold!=None: 
      self.maxCoordinates = [] 
      for x_item in range(MAXIMUM_PLOTS): 
       self.maxCoordinates.append((x_item, self.maxThreshold)) 
      #endfor 
      self.maxLine = plot.PolyLine(self.maxCoordinates, colour="green", width=1) 
      self.maxMarker = plot.PolyMarker(self.maxCoordinates, colour="green", marker='dot') 
      self.lines[1] = self.maxMarker 
     #endif 

    def _update_live_param(self, liveParam, minParam, maxParam): 
     if minParam!=None: 
      self.minThreshold = int(minParam) 
      self._update_min_threshold() 
     #endif 

     if maxParam!=None: 
      self.maxThreshold = int(maxParam) 
      self._update_max_threshold() 
     #endif 

     if liveParam!=None:    
      self._update_coordinates(int(liveParam)) 
     #endif 

    def _update_coordinates(self, newValue): 
     newList = []   
     for x,y in self.coordinates[1:]:    
      newList.append((x-1, y)) 
     #endfor 
     newList.append((x, newValue)) 
     print "New list", newList 

     self.line = (plot.PolyLine(newList, colour=self.plotColour, width=1)) 
     self.lines[0] = self.line 
     self.coordinates = newList 

    def _MyLIVE_MAGIC_refresh__(self, liveParam=None, minParam=None, maxParam=None): 
     self._update_live_param(liveParam, minParam, maxParam) 
     self.gc = plot.PlotGraphics(self.lines, self.title, 'Time', 'Value') 
     self.plotter.Draw(self.gc, xAxis=(0, MAXIMUM_PLOTS), yAxis=(self.ymin, self.ymax))    
     self.plotter.Refresh()    
     self.frame1.Refresh() 
関連する問題