问题描述
我对使用 tkinter 还很陌生,我想制作一个用于练习的小用户界面。我选择绘制洛伦兹系统,同时允许用户配置输入参数。
我已经有一个图表和连接的输入字段,我可以显示静态图。我的下一步是尝试展示一个动画情节。然而,这是我遇到问题的地方。我似乎无法在嵌入的图形中显示动画。在下面的代码中,您可以看到我更改了 plot_animated()
函数以创建新图形和轴,并且效果很好,但是当我将它们更改为使用 self.figure
和 self.ax
时,没有任何显示情节。
以下是我的 UI 实现:
from tkinter import *
from matplotlib import animation
from matplotlib.backends.backend_tkagg import figureCanvasTkAgg
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.pyplot as plt
from lorenz_model import run_lorenz
class LorenzUI:
input_width = 10
def __init__(self):
self.root = Tk()
self.root.title("Lorenz Attractor")
self.root.geometry("1290x960")
self.chart_fr = Frame(self.root)
self.figure = plt.figure()
self.figure.tight_layout()
self.ax = p3.Axes3D(self.figure)
self.canvas = figureCanvasTkAgg(self.figure,master=self.chart_fr)
self.canvas.get_tk_widget().grid(row=0,column=0,sticky="nsew")
self.input_fr = Frame(self.root,relief=RAISED,bd=2)
self.init_x_lbl = Label(self.input_fr,text="Initial X")
self.init_x_input = Entry(self.input_fr,width=self.input_width)
self.init_y_lbl = Label(self.input_fr,text="Initial Y")
self.init_y_input = Entry(self.input_fr,width=self.input_width)
self.init_z_lbl = Label(self.input_fr,text="Initial Z")
self.init_z_input = Entry(self.input_fr,width=self.input_width)
self.rho_lbl = Label(self.input_fr,text="Rho")
self.rho_input = Entry(self.input_fr,width=self.input_width)
self.sigma_lbl = Label(self.input_fr,text="Sigma")
self.sigma_input = Entry(self.input_fr,width=self.input_width)
self.beta_lbl = Label(self.input_fr,text="Beta")
self.beta_input = Entry(self.input_fr,width=self.input_width)
self.time_lbl = Label(self.input_fr,text="Sim Time")
self.time_input = Entry(self.input_fr,width=self.input_width)
self.is_animated = Intvar(value=1)
self.animate_chk = Checkbutton(self.input_fr,text="Animate?",variable=self.is_animated)
self.run_btn = Button(self.input_fr,text="Run",command=self.generate_model)
self.stop_btn = Button(self.input_fr,text="Stop")
self.reset_btn = Button(self.input_fr,text="Reset Defaults",command=self.set_defaults)
self.root.rowconfigure(0,minsize=50,weight=1)
self.root.columnconfigure(0,minsize=800,weight=1)
self.init_x_lbl.grid(row=0,padx=5,pady=5)
self.init_x_input.grid(row=0,column=1,pady=5)
self.init_y_lbl.grid(row=1,pady=5)
self.init_y_input.grid(row=1,pady=5)
self.init_z_lbl.grid(row=2,pady=5)
self.init_z_input.grid(row=2,pady=5)
self.rho_lbl.grid(row=4,pady=5)
self.rho_input.grid(row=4,pady=5)
self.sigma_lbl.grid(row=5,pady=5)
self.sigma_input.grid(row=5,pady=5)
self.beta_lbl.grid(row=6,pady=5)
self.beta_input.grid(row=6,pady=5)
self.time_lbl.grid(row=7,pady=5)
self.time_input.grid(row=7,pady=5)
self.animate_chk.grid(row=8,pady=5)
self.run_btn.grid(row=9,pady=5)
self.stop_btn.grid(row=9,pady=5)
self.reset_btn.grid(row=10,pady=5)
self.chart_fr.grid(row=0,sticky="nse")
self.input_fr.grid(row=0,sticky="nsew")
self.set_defaults()
@staticmethod
def __set_default(field,value):
field.delete(0,END)
field.insert(0,value)
def set_defaults(self):
self.__set_default(self.init_x_input,1.0)
self.__set_default(self.init_y_input,1.0)
self.__set_default(self.init_z_input,1.0)
self.__set_default(self.rho_input,28.0)
self.__set_default(self.sigma_input,10.0)
self.__set_default(self.beta_input,2.666667)
self.__set_default(self.time_input,40.0)
self.animate_chk.select()
def generate_model(self):
x = float(self.init_x_input.get())
y = float(self.init_y_input.get())
z = float(self.init_z_input.get())
rho = float(self.rho_input.get())
sigma = float(self.sigma_input.get())
beta = float(self.beta_input.get())
t = float(self.time_input.get())
dt = 0.01 # Todo Needed as Input?
self.model = run_lorenz([x,y,z],t,dt,rho,sigma,beta)
if self.is_animated.get():
self.__plot_animated()
else:
self.__plot_static()
def __plot_animated(self):
figure = plt.figure()
ax = p3.Axes3D(figure)
ax.clear()
ax.set_xlim3d([min(self.model[0]),max(self.model[0])])
ax.set_ylim3d([min(self.model[1]),max(self.model[1])])
ax.set_zlim3d([min(self.model[2]),max(self.model[2])])
n_frames = len(self.model[0])
line,= ax.plot(self.model[0,0:1],self.model[1,self.model[2,0:1])
self.ani = animation.FuncAnimation(figure,self.__animate,n_frames,fargs=(self.model,line),interval=1,blit=False)
plt.show()
def __animate(self,num,data,line):
line.set_data(data[:2,:num])
line.set_3d_properties(data[2,:num])
def __plot_static(self):
self.ax.clear()
self.ax.plot(self.model[0,:],:])
self.canvas.draw()
def run(self):
self.root.mainloop()
import numpy as np
from scipy.integrate import odeint
def f(state,beta):
x,z = state # Unpack the state vector
return sigma * (y - x),x * (rho - z) - y,x * y - beta * z # Derivatives
def run_lorenz(initial_state,beta):
times = np.arange(0.0,dt)
result = odeint(f,initial_state,times,args=(rho,beta))
return np.array(np.array(result).T)
from lorenz_ui import LorenzUI
if __name__ == '__main__':
app = LorenzUI()
app.run()
所以我真的有两个问题。
在此先感谢您的帮助。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)