2012-08-28 13 views
7

Próbuję zbudować interaktywną fabułę. Ten ma wyczyścić figurę, jeśli kliknięto w osie i narysować koło w przypadkowym miejscu. Kod jest w następujący sposób:Jak pozbyć się maksymalnego błędu głębokości rekursji podczas interaktywnego kreślenia?

import matplotlib.pyplot as plt 
import random 


def draw_circle(event): 
    if event.inaxes: 
     print(event.xdata, event.ydata) 
     plt.cla() 
     a = random.randint(0,100) 
     b = random.randint(0,100) 
     s, = plt.plot(a,b,'o', ms=100, color="blue",visible=True) 
     plt.show() 


fig = plt.figure() 
ax = plt.subplot(111) 
s, = plt.plot(1,2,'o', ms=100, color="blue",visible=True) 
plt.connect("button_press_event", draw_circle) 
plt.show() 

Po kliknięciu na 42 razy, przerwach programu i pojawia się następujący traceback:

Exception in Tkinter callback 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1413, in __call__ 
    return self.func(*args) 
    File "/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py", line 286, in button_press_event 
    FigureCanvasBase.button_press_event(self, x, y, num, guiEvent=event) 
    File "/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py", line 1632, in button_press_event 
    self.callbacks.process(s, mouseevent) 
    File "/usr/lib/pymodules/python2.7/matplotlib/cbook.py", line 262, in process 
    proxy(*args, **kwargs) 
    File "/usr/lib/pymodules/python2.7/matplotlib/cbook.py", line 192, in __call__ 
    return mtd(*args, **kwargs) 
    File "/home/almarahat/Dropbox/python/GUI/Testing site/test_rt/baud_test.py", line 8, in draw_circle 
    plt.cla() 
    File "/usr/lib/pymodules/python2.7/matplotlib/pyplot.py", line 2784, in cla 
    ret = gca().cla() 
    File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 842, in cla 
    spine.cla() 
    File "/usr/lib/pymodules/python2.7/matplotlib/spines.py", line 157, in cla 
    self.axis.cla() 
    File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 731, in cla 
    self.reset_ticks() 
    File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 744, in reset_ticks 
    self.majorTicks.extend([self._get_tick(major=True)]) 
    File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 1553, in _get_tick 
    return XTick(self.axes, 0, '', major=major, **tick_kw) 
    File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 141, in __init__ 
    self.tick2line = self._get_tick2line() 
    File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 401, in _get_tick2line 
    l.set_transform(self.axes.get_xaxis_transform(which='tick2')) 
    File "/usr/lib/pymodules/python2.7/matplotlib/axes.py", line 586, in get_xaxis_transform 
    return self.spines['top'].get_spine_transform() 
    File "/usr/lib/pymodules/python2.7/matplotlib/spines.py", line 374, in get_spine_transform 
    self._ensure_position_is_set() 
    File "/usr/lib/pymodules/python2.7/matplotlib/spines.py", line 140, in _ensure_position_is_set 
    self.set_position(self._position) 
    File "/usr/lib/pymodules/python2.7/matplotlib/spines.py", line 365, in set_position 
    self.axis.cla() 
    File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 731, in cla 
    self.reset_ticks() 
    File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 744, in reset_ticks 
    self.majorTicks.extend([self._get_tick(major=True)]) 
    File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 1553, in _get_tick 
    return XTick(self.axes, 0, '', major=major, **tick_kw) 
    File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 140, in __init__ 
    self.tick1line = self._get_tick1line() 
    File "/usr/lib/pymodules/python2.7/matplotlib/axis.py", line 383, in _get_tick1line 
    zorder=self._zorder, 
    File "/usr/lib/pymodules/python2.7/matplotlib/lines.py", line 195, in __init__ 
    self._marker = MarkerStyle() 
    File "/usr/lib/pymodules/python2.7/matplotlib/markers.py", line 112, in __init__ 
    self.set_marker(marker) 
    File "/usr/lib/pymodules/python2.7/matplotlib/markers.py", line 171, in set_marker 
    self._recache() 
    File "/usr/lib/pymodules/python2.7/matplotlib/markers.py", line 116, in _recache 
    self._path = Path(np.empty((0,2))) 
    File "/usr/lib/pymodules/python2.7/matplotlib/path.py", line 112, in __init__ 
    if ma.isMaskedArray(vertices): 
    File "/usr/local/lib/python2.7/dist-packages/numpy-1.6.2-py2.7-linux-x86_64.egg/numpy/ma/core.py", line 5683, in isMaskedArray 
    return isinstance(x, MaskedArray) 
RuntimeError: maximum recursion depth exceeded while calling a Python object 

W tym momencie, nie jestem pewien, gdzie występuje rekurencja i jak złagodzić ten błąd.

Rozumiem (z innego Q & As), że mogę zwiększyć mój limit stosu i obejść problem. Jednak nie uważam tego za rozwiązanie w tym konkretnym przypadku i chciałbym dojść do sedna tego.

Każda pomoc będzie doceniona.

Z góry dziękuję.

Dodatkowe informacje:

  • Głównym funkcjonalności, które obejmują kwestie rozliczeń postać i rysunek czegoś nowego o kliknięcie na płótnie.
  • Kliknięcie nie podnosi tego błędu, jeśli nie próbuję narysować czegoś. Tak więc podejrzewam, że brakuje mi czegoś w obsłudze matplotlib.

Odpowiedz

7

Zamiast plt.show(), z poziomu połączenia zwrotnego plt.draw(). Problem polega na tym, że plt.show uruchamia pulpit główny biblioteki GUI; po prostu chcesz zaktualizować to, co jest pokazane w istniejącym mainloopie. Używając backendu Qt, twój kod wyświetliłby błąd QCoreApplication::exec: The event loop is already running.

Więcej informacji na temat interaktywnego korzystania z Matplotlib można znaleźć pod numerem What is interactive mode?.

+0

Genialny ... Pozdrawiam. –

Powiązane problemy