将 Matplotlib 动画图嵌入到 Tkinter 中
Embedding a Matplotlib Animated Graph into Tkinter
我正在创建一个程序来模拟不同的行星轨道,虽然我已经完成了设计,但我正在努力将动画情节嵌入到 GUI 本身中。动画本身有效,但使用 plt.subplots() 而不是 plt.Figure()
这是我要嵌入的动画情节:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
global angles
angles = np.linspace(0,2*np.pi,360)
E_semi_major_axis = 149.596e6
E_eccentricity = 0.017
E_semi_latus = E_semi_major_axis*(1 - (E_eccentricity**2))
M_semi_major_axis = 227.923e6
M_eccentricity = 0.0935
M_semi_latus = M_semi_major_axis*(1 - (M_eccentricity**2))
def calc_Traj(semi_major_axis, semi_latus, eccentricity, r, x, y):
for i in angles:
val = semi_latus / (1 + (eccentricity*np.cos(i)))
r.append(val)
valx = (semi_major_axis*(np.cos(i) - eccentricity))/1e8
valy = (semi_major_axis*(np.sqrt(1 - (eccentricity**2)))*np.sin(i))/1e8
x.append(valx)
y.append(valy)
return r,x,y
def cal_Traj_peri_alph(semi_major_axis, semi_latus, eccentricity):
minmax = [0, np.pi]
for i in minmax:
val = semi_latus / (1 + (eccentricity*np.cos(i)))
valx = semi_major_axis*(np.cos(i) - eccentricity)
print('For Phi = {0} we have that r={1}, x={2}'.format(i, val, valx))
##################################
E_r, E_x, E_y = [], [], []
E_r, E_x, E_y = calc_Traj(E_semi_major_axis, E_semi_latus, E_eccentricity, E_r, E_x, E_y)
print("Perihelion and Alphelion Data for Earth:")
cal_Traj_peri_alph(E_semi_major_axis, E_semi_latus, E_eccentricity)
##################################
print("Perihelion and Alphelion Data for Mars:")
M_r, M_x, M_y = [], [], []
M_r, M_x, M_y = calc_Traj(M_semi_major_axis, M_semi_latus, M_eccentricity, M_r, M_x, M_y)
cal_Traj_peri_alph(M_semi_major_axis, M_semi_latus, M_eccentricity)
##################################
fig, ax = plt.subplots()
l = plt.plot(E_x, E_y)
l = plt.plot(M_x, M_y)
ax = plt.axis([-3,3,-3,3])
EarthDot, = plt.plot([0], [np.sin(0)], 'bo')
##MarsDot, = plt.plot([0], [np.sin(0)], 'ro')
dot, = plt.plot(0,0, 'yo')
def animate1(i):
EarthDot.set_data((E_semi_major_axis*(np.cos(i) - E_eccentricity))/1e8, (E_semi_major_axis*(np.sqrt(1 - (E_eccentricity**2)))*np.sin(i))/1e8)
return EarthDot,
# create animation using the animate() function
myAnimation = animation.FuncAnimation(fig, animate1, frames=np.linspace(0,2*np.pi,360), \
interval=10, blit=True, repeat=True)
plt.show()
这是我尝试实现它的尝试(嗯,只是火星的轨道):
#---------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
M_semi_major_axis = 227.923e6
M_eccentricity = 0.0935
M_semi_latus = M_semi_major_axis*(1 - (M_eccentricity**2))
global angles
angles = np.linspace(0,2*np.pi,360)
def calc_Traj(semi_major_axis, semi_latus, eccentricity, r, x, y):
for i in angles:
val = semi_latus / (1 + (eccentricity*np.cos(i)))
r.append(val)
valx = (semi_major_axis*(np.cos(i) - eccentricity))/1e8
valy = (semi_major_axis*(np.sqrt(1 - (eccentricity**2)))*np.sin(i))/1e8
x.append(valx)
y.append(valy)
return r,x,y
##################################
print("Perihelion and Alphelion Data for Mars:")
M_r, M_x, M_y = [], [], []
M_r, M_x, M_y = calc_Traj(M_semi_major_axis, M_semi_latus, M_eccentricity, M_r, M_x, M_y)
##################################
fig = plt.Figure()
#x = np.arange(0, 2*np.pi, 0.01) # x-array
def animate(i):
MarsDot.set_data((M_semi_major_axis*(np.cos(i) - M_eccentricity))/1e8, (M_semi_major_axis*(np.sqrt(1 - (M_eccentricity**2)))*np.sin(i))/1e8) # update the data
return MarsDot,
root = Tk.Tk()
label = Tk.Label(root,text="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)
orbitPath, = ax.plot(M_x, M_y)
MarsDot, = ax.plot(0, np.sin(0))
ani = animation.FuncAnimation(fig, animate, frames=np.linspace(0,2*np.pi,360), interval=10, blit=True)
Tk.mainloop()
我得到的结果只是一个带有轨道图的嵌入图,但缺少动画部分。
目前,我只想让嵌入式动画正常工作,任何低效的地方我都可以解决并在以后纠正。
在此先致歉并致谢!
您的代码运行良好,只是您没有为 MarsDot
提供标记,所以结果是不可见的。
尝试:
MarsDot, = ax.plot(0, np.sin(0), 'ro') # Draws Mars' position with a red circle
我正在创建一个程序来模拟不同的行星轨道,虽然我已经完成了设计,但我正在努力将动画情节嵌入到 GUI 本身中。动画本身有效,但使用 plt.subplots() 而不是 plt.Figure()
这是我要嵌入的动画情节:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
global angles
angles = np.linspace(0,2*np.pi,360)
E_semi_major_axis = 149.596e6
E_eccentricity = 0.017
E_semi_latus = E_semi_major_axis*(1 - (E_eccentricity**2))
M_semi_major_axis = 227.923e6
M_eccentricity = 0.0935
M_semi_latus = M_semi_major_axis*(1 - (M_eccentricity**2))
def calc_Traj(semi_major_axis, semi_latus, eccentricity, r, x, y):
for i in angles:
val = semi_latus / (1 + (eccentricity*np.cos(i)))
r.append(val)
valx = (semi_major_axis*(np.cos(i) - eccentricity))/1e8
valy = (semi_major_axis*(np.sqrt(1 - (eccentricity**2)))*np.sin(i))/1e8
x.append(valx)
y.append(valy)
return r,x,y
def cal_Traj_peri_alph(semi_major_axis, semi_latus, eccentricity):
minmax = [0, np.pi]
for i in minmax:
val = semi_latus / (1 + (eccentricity*np.cos(i)))
valx = semi_major_axis*(np.cos(i) - eccentricity)
print('For Phi = {0} we have that r={1}, x={2}'.format(i, val, valx))
##################################
E_r, E_x, E_y = [], [], []
E_r, E_x, E_y = calc_Traj(E_semi_major_axis, E_semi_latus, E_eccentricity, E_r, E_x, E_y)
print("Perihelion and Alphelion Data for Earth:")
cal_Traj_peri_alph(E_semi_major_axis, E_semi_latus, E_eccentricity)
##################################
print("Perihelion and Alphelion Data for Mars:")
M_r, M_x, M_y = [], [], []
M_r, M_x, M_y = calc_Traj(M_semi_major_axis, M_semi_latus, M_eccentricity, M_r, M_x, M_y)
cal_Traj_peri_alph(M_semi_major_axis, M_semi_latus, M_eccentricity)
##################################
fig, ax = plt.subplots()
l = plt.plot(E_x, E_y)
l = plt.plot(M_x, M_y)
ax = plt.axis([-3,3,-3,3])
EarthDot, = plt.plot([0], [np.sin(0)], 'bo')
##MarsDot, = plt.plot([0], [np.sin(0)], 'ro')
dot, = plt.plot(0,0, 'yo')
def animate1(i):
EarthDot.set_data((E_semi_major_axis*(np.cos(i) - E_eccentricity))/1e8, (E_semi_major_axis*(np.sqrt(1 - (E_eccentricity**2)))*np.sin(i))/1e8)
return EarthDot,
# create animation using the animate() function
myAnimation = animation.FuncAnimation(fig, animate1, frames=np.linspace(0,2*np.pi,360), \
interval=10, blit=True, repeat=True)
plt.show()
这是我尝试实现它的尝试(嗯,只是火星的轨道):
#---------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
M_semi_major_axis = 227.923e6
M_eccentricity = 0.0935
M_semi_latus = M_semi_major_axis*(1 - (M_eccentricity**2))
global angles
angles = np.linspace(0,2*np.pi,360)
def calc_Traj(semi_major_axis, semi_latus, eccentricity, r, x, y):
for i in angles:
val = semi_latus / (1 + (eccentricity*np.cos(i)))
r.append(val)
valx = (semi_major_axis*(np.cos(i) - eccentricity))/1e8
valy = (semi_major_axis*(np.sqrt(1 - (eccentricity**2)))*np.sin(i))/1e8
x.append(valx)
y.append(valy)
return r,x,y
##################################
print("Perihelion and Alphelion Data for Mars:")
M_r, M_x, M_y = [], [], []
M_r, M_x, M_y = calc_Traj(M_semi_major_axis, M_semi_latus, M_eccentricity, M_r, M_x, M_y)
##################################
fig = plt.Figure()
#x = np.arange(0, 2*np.pi, 0.01) # x-array
def animate(i):
MarsDot.set_data((M_semi_major_axis*(np.cos(i) - M_eccentricity))/1e8, (M_semi_major_axis*(np.sqrt(1 - (M_eccentricity**2)))*np.sin(i))/1e8) # update the data
return MarsDot,
root = Tk.Tk()
label = Tk.Label(root,text="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)
orbitPath, = ax.plot(M_x, M_y)
MarsDot, = ax.plot(0, np.sin(0))
ani = animation.FuncAnimation(fig, animate, frames=np.linspace(0,2*np.pi,360), interval=10, blit=True)
Tk.mainloop()
我得到的结果只是一个带有轨道图的嵌入图,但缺少动画部分。
目前,我只想让嵌入式动画正常工作,任何低效的地方我都可以解决并在以后纠正。
在此先致歉并致谢!
您的代码运行良好,只是您没有为 MarsDot
提供标记,所以结果是不可见的。
尝试:
MarsDot, = ax.plot(0, np.sin(0), 'ro') # Draws Mars' position with a red circle