For a project I am working on a simple harmonic motion simulator (How a mass oscillates over time). I have got the data produced correctly and already have a graph produced within a tkinter frame work. At the moment it only shows a static graph where my objective is to display the graph as an animation over time.
So for ease sake I have created a mock up of the programme using the following code:
#---------Imports
from numpy import arange, sin, pi
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import tkinter as Tk
from tkinter import ttk
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
#---------End of imports
fig, ax = plt.subplots()
x = np.arange(0, 2*np.pi, 0.01)        # x-array
line, = ax.plot(x, np.sin(x))
def animate(i):
    line.set_ydata(np.sin(x+i/10.0))  # update the data
    return line,
ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), interval=25, blit=False)
#plt.show() #What I want the object in tkinter to appear as
root = Tk.Tk()
label = ttk.Label(root,text="SHM Simulation").grid(column=0, row=0)
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.show()
canvas.get_tk_widget().grid(column=0,row=1)
Tk.mainloop()
This code will display the animation that I want in the tkinter frame work when the plt.show() is uncommented. I would like to be able to place that animation within the framework of tkinter.
I have also been on the matplotlib website and viewed all of the animation examples and none of them have helped. I have also looked on Embedding an animated matplotlib in tk and that has placed the tkinter button within pyplot figure, whereas I would like to place the figure within a tkinter frame.
So just to clarify, I would like to be able to place the animation produced when plt.show() is uncommented in a tkinter frame, ie root = tk().
Based on the answer of user151522 that didnt work for me at the first try, i made a few modifications to work in python 3.7:
#---------Imports
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
#---------End of imports
from tkinter import Frame,Label,Entry,Button
class Window(Frame):
    def __init__(self, master = None):
        Frame.__init__(self, master)
        self.master = master
        self.init_window()
    def Clear(self):      
        print("clear")
        self.textAmplitude.insert(0, "1.0")
        self.textSpeed.insert(0, "1.0")       
    def Plot(self):
        self.v = float(self.textSpeed.get())
        self.A = float(self.textAmplitude.get())
    def animate(self,i):
        self.line.set_ydata(self.A*np.sin(self.x+self.v*i))  # update the data
        return self.line,
    def init_window(self):
        self.master.title("Use Of FuncAnimation in tkinter based GUI")
        self.pack(fill='both', expand=1)     
        #Create the controls, note use of grid
        self.labelSpeed = Label(self,text="Speed (km/Hr)",width=12)
        self.labelSpeed.grid(row=0,column=1)
        self.labelAmplitude = Label(self,text="Amplitude",width=12)
        self.labelAmplitude.grid(row=0,column=2)
        self.textSpeed = Entry(self,width=12)
        self.textSpeed.grid(row=1,column=1)
        self.textAmplitude = Entry(self,width=12)
        self.textAmplitude.grid(row=1,column=2)
        self.textAmplitude.insert(0, "1.0")
        self.textSpeed.insert(0, "1.0")
        self.v = 1.0
        self.A = 1.0
        self.buttonPlot = Button(self,text="Plot",command=self.Plot,width=12)        
        self.buttonPlot.grid(row=2,column=1)
        self.buttonClear = Button(self,text="Clear",command=self.Clear,width=12)
        self.buttonClear.grid(row=2,column=2)
        self.buttonClear.bind(lambda e:self.Clear)
        tk.Label(self,text="SHM Simulation").grid(column=0, row=3)
        self.fig = plt.Figure()
        self.x = 20*np.arange(0, 2*np.pi, 0.01)        # x-array
        self.ax = self.fig.add_subplot(111)
        self.line, = self.ax.plot(self.x, np.sin(self.x))        
        self.canvas = FigureCanvasTkAgg(self.fig, master=self)
        self.canvas.get_tk_widget().grid(column=0,row=4)
        self.ani = animation.FuncAnimation(self.fig, self.animate, np.arange(1, 200), interval=25, blit=False)
root = tk.Tk()
root.geometry("700x400")
app = Window(root)
tk.mainloop()
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With