2016-09-02 11 views
0

次のコードは、左クリックでキャンバスにポイントを追加し、右クリックして描いたポイントでポリラインを描き、ライン上にスライドポイントを描きます動いている。唯一の問題は、タイトル理由のために「スライド」した直後に実行が停止することです。この問題をどのように克服し、必要なだけスライドさせることができますか?matplotlib.pyplotを使用して「最大再帰深度を超えて戦う方法」

import matplotlib.pyplot as plt 


class DumbyRemove: 
    def __init__(self): 
     pass 

    def remove(self): 
     pass 

the_points = list() 
drawn_points = list() 
moving_point = DumbyRemove() 


def draw_polyline(): 
    global the_points, drawn_points 
    if len(the_points) < 2: 
     return 
    start_point = the_points[0] 
    for end_point in the_points[1:]: 
     xs = (start_point[0], end_point[0]) 
     ys = (start_point[1], end_point[1]) 
     start_point = end_point 
     line = plt.Line2D(xs, ys, marker='.', color=(0.7, 0.3, 0.3)) 
     plt.gcf().gca().add_artist(line) 
    drawn_points = drawn_points + the_points 
    the_points = list() 
    plt.show() 


def button_press_callback(event): 
    global the_points 

    if event.button == 1: 
     the_points.append((event.xdata, event.ydata)) 
     p = plt.Line2D((event.xdata, event.xdata), (event.ydata, event.ydata), marker='o', color='r') 
     plt.gcf().gca().add_artist(p) 
     plt.show() 
    else: 
     draw_polyline() 


def handle_motion(event): 
    global moving_point 
    if len(drawn_points) < 2: 
     return 
    x = event.xdata 
    start_point = drawn_points[0] 
    for end_point in drawn_points[1:]: 
     start_x, start_y = start_point 
     end_x, end_y = end_point 
     if end_x < start_x: 
      end_x, start_x = start_x, end_x 
      end_y, start_y = start_y, end_y 
     if start_x <= x <= end_x: 
      d = end_x - start_x 
      lam = (x - start_x)/d 
      y = start_y * (1 - lam) + end_y * lam 
      moving_point.remove() 
      moving_point = plt.Line2D((x, x), (y, y), marker='o', color='r') 
      plt.gcf().gca().add_artist(moving_point) 
      break 
     start_point = end_point 
    plt.show() 

fig = plt.gcf() 
fig.add_subplot(111, aspect='equal') 

fig.canvas.mpl_connect('button_press_event', button_press_callback) 
fig.canvas.mpl_connect('motion_notify_event', handle_motion) 

plt.show() 

トレースバック:

Exception in Tkinter callback 
    x = self.convert_xunits(self._x) 
    File "C:\Python27\lib\site-packages\matplotlib\artist.py", line 186, in convert_xunits 
    ax = getattr(self, 'axes', None) 
RuntimeError: maximum recursion depth exceeded while calling a Python object 
Exception in Tkinter callback 
Traceback (most recent call last): 
    File "C:\Python27\lib\lib-tk\Tkinter.py", line 1536, in __call__ 
    return self.func(*args) 
    File "C:\Python27\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 605, in destroy 
    Gcf.destroy(self._num) 
    File "C:\Python27\lib\site-packages\matplotlib\_pylab_helpers.py", line 60, in destroy 
    manager.canvas.mpl_disconnect(manager._cidgcf) 
    File "C:\Python27\lib\site-packages\matplotlib\backend_bases.py", line 2366, in mpl_disconnect 
    return self.callbacks.disconnect(cid) 
    File "C:\Python27\lib\site-packages\matplotlib\cbook.py", line 552, in disconnect 
    del functions[function] 
    File "C:\Python27\lib\weakref.py", line 327, in __delitem__ 
    del self.data[ref(key)] 
RuntimeError: maximum recursion depth exceeded 
+0

スタックトレースで完全なエラーメッセージを投稿してください。実行は、実際にスライドした後(あなたの状態で)、または*スライディング中に(あなたが示唆するように)停止しますか?私は何が繰り返されているのかはっきりしていません。 – Prune

+0

@Pruneエラーメッセージの最後を追加しました。エラーは「滑り」の間に現れます。私はそれがマシン上で実験をして見るのは簡単だと思います:) –

+0

これは正しく読めますか? *あなたのコードのどれもコールスタックに表示されません! – Prune

答えて

1

オーケー、野郎は、私はそれを得ました。この問題は、イベントハンドラでplt.show()を集中的に使用していることが原因でした。 event.canvas.draw()に置き換えてください。

関連する問題