问题
I am new to python, and I want to display the graph in a new window after clicking the button, but I don't know what is the error occur as I followed the documentation. I keep getting the same error as below.
Traceback (most recent call last):
File "C:\Users\User\Desktop\IMPORTANT NOTES\python to firebase\GUI\increment.py", line 88, in <module>
ani = animation.FuncAnimation(f, animate, interval=1000)
File "C:\Users\User\AppData\Local\Programs\Python\Python35-32\lib\site-packages\matplotlib\animation.py", line 1462, in __init__
TimedAnimation.__init__(self, fig, **kwargs)
File "C:\Users\User\AppData\Local\Programs\Python\Python35-32\lib\site-packages\matplotlib\animation.py", line 1225, in __init__
event_source = fig.canvas.new_timer()
AttributeError: 'NoneType' object has no attribute 'new_timer'
Here is my code.
from tkinter import *
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import matplotlib.animation as animation
import matplotlib.pyplot as plt
from matplotlib import style
style.use("ggplot")
f = Figure(figsize = (5,5), dpi = 100)
a = f.add_subplot(111)
#a.plot([1,2,3,4,5,6,7,8],[5,4,8,6,3,2,7,9])
def animate(i):
pullData = open ("sampleData.txt","r").read()
datalist = pullData.split('\n')
xList = []
yList = []
for eachLine in dataList:
if len (eachLine)>1:
x,y=eachLine.split(',')
xList.append(int (x))
yList.append(int (y))
a.clear()
a.plot(xList,yList)
class Application(Frame):
"""A GUI app with some buttons."""
def __init__(self, master):
""" Initialze frame"""
Frame.__init__(self, master)
self.grid()
self.button_clicks=0 #count the number of button click
self.create_widgets()
def create_widgets(self):
"""Create button which displays number of clicks."""
#Button1
self.button1 = Button(self)
self.button1 ["text"]="in"
self.button1["command"] = self.update_news
self.button1.grid()
def update_news(self):
toplevel = Toplevel()
canvas = FigureCanvasTkAgg(f,toplevel)
canvas.show()
canvas.get_tk_widget().pack()
toolbar = NavigationToolbar2TkAgg(canvas,toplevel)
toolbar.update()
canvas._tkcanvas.pack()
#Building the window
root = Tk()
root.title("Buttons")
root.geometry("200x300")
app = Application(root)
#MainLoop
ani = animation.FuncAnimation(f, animate, interval=1000)
root.mainloop()
回答1:
You need to make sure to only start the animation once the figure is added to the canvas. It is then also crucial to keep a reference to the FuncAnimation instance.
One intuitive way of doing this is to create the figure in the update_news method and only create the animation after the figure is been bound to the canvas. Using class variables (self) for the figure, axes and canvas ensures not to loose the reference.
from tkinter import *
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import matplotlib.animation as animation
import matplotlib.pyplot as plt
from matplotlib import style
import numpy as np
style.use("ggplot")
class Application(Frame):
"""A GUI app with some buttons."""
def __init__(self, master):
""" Initialze frame"""
Frame.__init__(self, master)
self.grid()
self.button_clicks=0 #count the number of button click
self.create_widgets()
def create_widgets(self):
"""Create button which displays number of clicks."""
#Button1
self.button1 = Button(self)
self.button1 ["text"]="in"
self.button1["command"] = self.update_news
self.button1.grid()
def update_news(self):
toplevel = Toplevel()
self.f = Figure(figsize = (5,5), dpi = 100)
self.a = self.f.add_subplot(111)
self.canvas = FigureCanvasTkAgg(self.f,toplevel)
self.canvas.show()
self.canvas.get_tk_widget().pack()
toolbar = NavigationToolbar2TkAgg(self.canvas,toplevel)
toolbar.update()
self.canvas._tkcanvas.pack()
self.ani = animation.FuncAnimation(app.f, app.animate, frames=100,interval=100)
def animate(self,i):
"""
pullData = open ("sampleData.txt","r").read()
datalist = pullData.split('\n')
xList = []
yList = []
for eachLine in dataList:
if len (eachLine)>1:
x,y=eachLine.split(',')
xList.append(int (x))
yList.append(int (y))
"""
xList = np.arange(i+1)
yList = np.sin(xList/10.)
self.a.clear()
self.a.plot(xList,yList)
#Building the window
root = Tk()
root.title("Buttons")
root.geometry("200x300")
app = Application(root)
#MainLoop
root.mainloop()
Note: In newer versions of matplotlib you should use NavigationToolbar2Tk instead of NavigationToolbar2TkAgg.
来源:https://stackoverflow.com/questions/42815385/python-error-using-animation-funcanimation