1

wxPythonを使用する「本番」アプリケーションで、matplotlibでデータのリアルタイムプロットを実行しようとしています。私はこの目的でChacoを使用していましたが、将来的にはさまざまな理由でChacoを避けようとしています。その理由のひとつは、十分に文書化されていないため、必要なときにChacoのソースコードを読むのに長い時間を費やさなければならないことです。最小の機能でさえ私のプロットの1つに追加します。Chacoがmatplotlibに勝つ1つの側面は速度にあるので、私はmatplotlibから許容できるパフォーマンスを得る方法を模索しています。

matplotlibの高速プロットで広く使用されている手法の1つは、頻繁に更新するプロットの要素に設定animatedTrue、背景(軸、目盛りなど)を1回だけ描​​画し、そのcanvas.copy_from_bbox()方法を使用して次のことを行うことです。背景を保存します。次に、新しいforeground(プロットトレースなど)を描画するときにcanvas.restore_region()、事前にレンダリングされた背景を画面にコピーしてから、新しい前景axis.draw_artist()canvas.blit()それを画面に描画するために使用します。

FigureCanvasWxAggをwxPythonフレームに埋め込み、ランダムデータの単一のトレースを45FPSで表示しようとする非常に単純な例を作成しました。プログラムがデフォルトサイズ(ソースにハードコードされている)のフレームで実行されている場合、私のマシンでは1秒あたり最大13〜14フレームを達成します。ウィンドウを最大化すると、更新は約5.5FPSに低下します。特に、リアルタイムでレンダリングする要素を追加し始めたら、これは私のアプリケーションにとって十分な速度ではないと思います。

私のコードはここに投稿されています:basic_fastplot.py

これをもっと速くできるかどうか疑問に思ったので、コードのプロファイルを作成したところ、処理時間の最大の消費者はcanvas.blit()99行目と109行目の呼び出しであることがわかりました。この時間のは、への特定の呼び出しに費やされMemoryDC.SelectObject()ます。周囲のコードにはいくつかの呼び出しがありますがSelectObject、以下にマークされているものだけがかなりの時間を要します。

matplotlibソースから、backend_wxagg.py:

class FigureCanvasWxAgg(FigureCanvasAgg, FigureCanvasWx):
    # ...

    def blit(self, bbox=None):
    """
    Transfer the region of the agg buffer defined by bbox to the display.
    If bbox is None, the entire buffer is transferred.
    """
    if bbox is None:
        self.bitmap = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
        self.gui_repaint()
        return

    l, b, w, h = bbox.bounds
    r = l + w
    t = b + h
    x = int(l)
    y = int(self.bitmap.GetHeight() - t)

    srcBmp = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
    srcDC = wx.MemoryDC()
    srcDC.SelectObject(srcBmp)          # <<<< Most time is spent here, 30milliseconds or more!

    destDC = wx.MemoryDC()
    destDC.SelectObject(self.bitmap)

    destDC.BeginDrawing()
    destDC.Blit(x, y, int(w), int(h), srcDC, x, y)
    destDC.EndDrawing()

    destDC.SelectObject(wx.NullBitmap)
    srcDC.SelectObject(wx.NullBitmap)
    self.gui_repaint()

私の質問:

  • SelectObject()は、これほど時間がかかっていることを何をしているのでしょうか。ポインタなどを設定するだけで、コピーや計算はあまり行わないと思っていました。
  • これを高速化できる方法はありますか(フルスクリーンで10 FPSを取得するため)?
4

0 に答える 0