2

シリアルポートから連続データを読み取るためのGUIを開発しています。データを読み取った後、いくつかの計算が行われ、結果がプロットされて更新されます(別名動的プロット)。この目的のために、matplotlibで提供されているwxバックエンドを使用します。これを行うには、基本的に配列を使用して結果を格納し、各計算の後に結果を追加し続け、グラフ全体を再プロットします。「動的」にするために、各反復のx軸の下限と上限を設定するだけです。で見つかったようなもの:

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

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

4

4 に答える 4

3

これを行うには、基本的に配列を使用して結果を保存し、そこに追加し続けます

古いデータを削除するか、n 番目ごとのエントリを削除して、この配列のサイズを制限してみてください (いずれにせよ、画面の解像度によってすべてのエントリが表示されなくなります)。何も失わないように、すべてのデータをディスクに書き込むと仮定します。

また、メモリ リークがないかコードを分析します。使用していて不要になったものの、参照がまだ残っているため、ガベージ コレクションの対象にはなりません。

于 2009-07-25T07:01:02.243 に答える
1

私はpythons Tkinterでそのようなコンポーネントを作成しました。ソースはこちら

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

于 2009-07-25T12:00:36.633 に答える
1

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

于 2009-07-25T12:23:40.653 に答える
0

私は実際にこの問題に遭遇しました(実際には、より多くのメンタルブロックです...)。

まず、wx Demo Codeから wx Plot コードをいくつかコピーして貼り付けました。

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

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

最後の 100 ~ 10,000 プロットを追跡するのに問題なく機能します。プリントスクリーンも含まれていたでしょうが、私はスタックオーバーフローに慣れすぎて許可されません:))

私のライブ パラメータは、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()
于 2011-10-19T15:19:34.707 に答える