I want to write a code where the animation function in matplotlib starts plotting only after the matplotlib button widget is clicked by me. Here are my steps:
I got successful in the storing the x and y coordinates but the press button doesn't give me the animated plot that I need. This is the first error I am facing.
The second error is my click event also stores the coordinates of where I press the button. I don't want coordinates during button press. I just the coordinates on the empty plot.
from matplotlib.widgets import Button
from matplotlib.animation import FuncAnimation
x_coord,y_coord = [],[]
fig = plt.figure()
axis = fig.add_subplot(111,xlim=(-5,15),ylim=(-5,15))
line, = axis.plot([],[],lw=3)
def init():
line.set_data([],[])
return line,
def animate(i):
x_points = [0,x_coord[i]]
y_points = [0,y_coord[i]]
line.set_data(x_points,y_points)
return line,
def onclick(event):
print(event.xdata,event.ydata)
x_coord.append(event.xdata)
y_coord.append(event.ydata)
def buttonPress(pressevent):
print('pressed')
print(x_coord)
ani = FuncAnimation(fig,animate,init_func=init,frames=len(x_coord),interval=100,blit=False)
cid = fig.canvas.mpl_connect('button_press_event',onclick)
axprev = plt.axes([0.5,0,0.1,0.1])
button = Button(axprev,'press')
button.on_clicked(buttonPress)
plt.show()```
The second error is easy to fix, you can test whether the click was in or out of the axes region by using event.inaxes
The animation issue is due to the fact that you are creating the animation object in a function, and that it is immediately garbage-collected at the end of the function. The [documentation for FuncAnimation][2]
states:
it is critical to keep a reference to the instance object. The animation is advanced by a timer (typically from the host GUI framework) which the Animation object holds the only reference to. If you do not hold a reference to the Animation object, it (and hence the timers), will be garbage collected which will stop the animation.
One way to get around that is to keep the animation object in a global variable. A cleaner way would be to encapsulate your code in a custom class and store the animation as a property of that class.
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.widgets import Button
x_coord, y_coord = [], []
fig = plt.figure()
axis = fig.add_subplot(111, xlim=(-5, 15), ylim=(-5, 15))
line, = axis.plot([], [], lw=3)
ani = None
def init():
line.set_data([], [])
return line,
def animate(i):
x_points = [0, x_coord[i]]
y_points = [0, y_coord[i]]
line.set_data(x_points, y_points)
return line,
def onclick(event):
if event.inaxes is axis:
print(event.xdata, event.ydata)
x_coord.append(event.xdata)
y_coord.append(event.ydata)
def buttonPress(pressevent):
global ani
print('pressed')
print(x_coord)
ani = FuncAnimation(fig, animate, init_func=init, frames=len(x_coord), interval=100, blit=False)
cid = fig.canvas.mpl_connect('button_press_event', onclick)
axprev = plt.axes([0.5, 0, 0.1, 0.1])
button = Button(axprev, 'press')
button.on_clicked(buttonPress)
plt.show()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.