Reputation: 673
The following code adds point on canvas by left click, draws a polyline with the drawn points by right click and also draws a sliding point on the lines while a cursor is moving. The only problem is that the execution stops pretty soon after "sliding" because of the title reason. How can I overcome this problem and slide as much as wanted?
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()
Traceback:
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
Upvotes: 1
Views: 2249
Reputation: 673
Okey, fellas, I got it. The problem was due to intensive use of plt.show() in the event handler. Replacing it with event.canvas.draw() does the job.
Upvotes: 5