2011-12-30 13 views
3

多角形でクリックされた最後の点とユーザーのマウスの間に線を描画するためにLine2Dを使用しようとしています。私の現在のコードは現在動作していますが、レンダリングの間にFOREVERだけ遅れているので、ラインがマウスの後ろに遅れてしまいます。現在、関連するコードは次のとおりです。MatlotLibのLine2Dレンダリングが遅い

#in constructor 
cid2 = self.ui.canvas2.mpl_connect('motion_notify_event', self.renderMeasureLine) 

#This gets called and is laggy 
def renderMeasureLine(self, mouseEvent):    
    if self.measuring and mouseEvent.inaxes == self.ui.canvas2.axes and len(self.pointListX) > 0: 

     if self.dotted_line in self.ui.canvas2.axes.lines: 
      self.ui.canvas2.axes.lines.remove(self.dotted_line) 
     self.dotted_line = Line2D([self.pointListX[-1],mouseEvent.xdata],[self.pointListY[-1],mouseEvent.ydata], 
            color=color, axes=self.ui.canvas2.axes, ls = '--') 
     self.ui.canvas2.axes.add_line(self.dotted_line) 
     self.ui.canvas2.draw() 

====================================== ========================

#mpl canvas class 
class MyDynamicMplCanvas(MyMplCanvas): 
    """A canvas that updates itself every second with a new plot.""" 
    def __init__(self, *args, **kwargs): 
     MyMplCanvas.__init__(self, *args, **kwargs) 
     self.colorMap = cmap.bone 

    def compute_initial_figure(self): 
     self.axes.imshow(self.data, cmap = cmap.bone) 

    def update_figure(self, dataOverride = None): 
     if self.data is not None or dataOverride is not none: 
      FigureCanvas.updateGeometry(self) 
      self.axes.clear() 
      if dataOverride is not None: 
       self.axes.imshow(dataOverride, cmap = self.getColorMap()) 
      else: 
       self.axes.imshow(self.data, cmap = self.getColorMap()) 
     self.draw() 

So基本的に、マウスが動くたびに、最後にクリックされたポリゴンポイントと現在の新しいマウス位置の間の点線を更新したいと考えています。これは動作しますが、それは超低速です。何か案は??

編集:何が起こっているのかの写真。点線は遅いです。

enter image description here

+1

blittingを使用すると、matplotlibはライン全体を更新するだけでFigure全体を再描画します。 matplotlibサイトには例があります。そうでなければ、matplotlibソースディレクトリのカーソルクラスのソースをよく見てください。 – tillsten

+0

ああ、これは私が探していたものですが、見つけられませんでした。私はチャンスを得るときにこれを撃つだろう。 – tylerthemiler

答えて

2

すべてのマウス移動のための新しいLine2Dを作成しないでください。 Line2Dは2点以上を持つことができます。代わりにLine2D.set_data()を使用して、Line2Dのデータを変更してください。

Line2Dを1つ描画すると、何千ものポイントを持つものは、必ずインスタンス化して描画するよりも速くなります。Line2D

def renderMeasureLine(self, mouseEvent):    
    if (self.measuring and mouseEvent.inaxes == self.ui.canvas2.axes 
      and len(self.pointListX) > 0): 
     if self.dotted_line in self.ui.canvas2.axes.lines: 
      x, y = self.dotted_line.get_data() 
      x.append(mouseEvent.xdata) 
      y.append(mouseEvent.ydata) 
      self.dotted_line.set_data(x, y) 
     else: 
      self.dotted_line = Line2D(
       [self.pointListX[-1],mouseEvent.xdata], 
       [self.pointListY[-1],mouseEvent.ydata], 
       color=color, axes=self.ui.canvas2.axes, ls = '--') 
      self.ui.canvas2.axes.add_line(self.dotted_line) 

     self.ui.canvas2.blit(self.ui.canvas2.axes.bbox) 
     self.ui.canvas2.draw_idle() 
+0

ありがとう、これは解決策に向かって私を得る、私はそれがマウスが移動し、レンダリングカウントで終了しない場合は、それが新しい行を描画するようにする方法を見つけることを試みる最後の時間を過ごした。 。matplotlibやqtで解読することはできません。(でも、ハッキングすることによって) – tylerthemiler

+0

実際には、マウスを動かすのをやめたときに、これはちょうど不安定になります。/おそらく、Line2Dを使うのは良い解決策ではありませんこの。 – tylerthemiler

+0

'renderMeasureLine'への呼び出し回数をカウントする代わりに、最後に描画された線の終点を覚えておく必要があります。次に、そのエンドポイントと新しいマウス位置の間の距離を計算します。その距離が 'dmin'より大きく、' dmax'よりも小さい場合は、線を描きます。 'dmin'は非常に短い行の描画を止め、' dmax'は不規則な行の描画を止めます。 – unutbu

関連する問題