Incrustar una animación matplotlib en un marco tkinter

Para un proyecto, estoy trabajando en un simulador de movimiento armónico simple (Cómo una masa oscila con el tiempo). Tengo los datos producidos correctamente y ya tengo un gráfico producido dentro de un marco de trabajo tkinter. En este momento solo muestra un gráfico estático donde mi objective es mostrar el gráfico como una animación a lo largo del tiempo.

Así que para simplificar, he creado una maqueta del progtwig usando el siguiente código:

#---------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() 

Este código mostrará la animación que quiero en el trabajo del marco tkinter cuando el plt.show () no esté comentado. Me gustaría poder colocar esa animación en el marco de tkinter.

También he estado en el sitio web de matplotlib y he visto todos los ejemplos de animación y ninguno de ellos me ha ayudado. También he consultado la pregunta ‘21179971’ en este sitio web y he colocado el botón tkinter dentro de la figura de un gráfico de puntos, mientras que me gustaría colocar la figura dentro de un marco tkinter.

Así que solo para aclarar, me gustaría poder colocar la animación producida cuando “# plt.show ()” no se ha comentado en un marco tkinter, es decir (root = tk ())

He modificado tu código:

 #---------Imports from numpy import arange, sin, pi from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from matplotlib.figure import Figure import Tkinter as Tk import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation #---------End of imports fig = plt.Figure() x = np.arange(0, 2*np.pi, 0.01) # x-array def animate(i): line.set_ydata(np.sin(x+i/10.0)) # update the data return line, root = Tk.Tk() label = Tk.Label(root,text="SHM Simulation").grid(column=0, row=0) canvas = FigureCanvasTkAgg(fig, master=root) canvas.get_tk_widget().grid(column=0,row=1) ax = fig.add_subplot(111) line, = ax.plot(x, np.sin(x)) ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), interval=25, blit=False) Tk.mainloop() 

Mi respuesta es una actualización de la respuesta anterior para trabajar con Python 3. Esto solo implica el uso de la importación ‘tkinter’ y no ‘Tkinter’.

Ejecuté el código de Spyder 3.1.4 usando Python 3.6.1 para habilitar la captura de pantalla vinculada a continuación. La pantalla depende del tiempo en tiempo real.

Una captura de pantalla de la animación SHM que se ejecuta con Python 3.6.1

introduzca la descripción de la imagen aquí

Esperemos que esta respuesta sea permitida. Es una respuesta a lo que realmente me interesaba, cuando inicialmente encontré esta pregunta, es decir, “Incrustar una animación de Matplotlib en una GUI basada en tkinter”.

El código que dio la captura de pantalla anterior se ha extendido. En este código, el canvas se ha colocado dentro de una definición de clase, junto con algunos códigos para dos botones de comando, estos botones no hacen “nada”, pero la estructura está ahí para que sea posible. un mayor desarrollo.

La siguiente captura de pantalla se realizó con la ayuda del código extendido.

Una captura de pantalla de la animación SHM que se ejecuta desde una GUI basada en tkinter

El código extendido utilizado para la captura de pantalla anterior se muestra a continuación.

 from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import tkinter as tk from tkinter import Frame,Label,Entry,Button import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation class Window(Frame): def __init__(self, master = None): Frame.__init__(self, master) self.master = master self.init_window() def Clear(self): x=0 # def Plot(self): # x=0 def init_window(self): def animate(i): self.line.set_ydata(np.sin(self.x+i/10.0)) # update the data return self.line, 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.buttonPlot = Button(self,text="Plot",command=self.Plot,width=12) self.buttonPlot = Button(self,text="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.Plot) self.buttonClear.bind(lambda e:self.Clear) tk.Label(self,text="SHM Simulation").grid(column=0, row=3) self.fig = plt.Figure() self.x = 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, animate, np.arange(1, 200), interval=25, blit=False) root = tk.Tk() root.geometry("700x400") app = Window(root) tk.mainloop()