因此,我正在尝试创建此函数以绘制质量弹簧减震器系统的图,并且我们应该能够基本上更改所需的值,该函数的值和滑块也应影响该图,我我在尝试绘制我的函数时遇到麻烦。我正在尝试在PlotWindow函数中使用我的solveMBK函数的函数中出现错误,我不确定如何包括滑块中的值以及在启动窗口中输入的其他值。这是我的代码:
import tkinter as tk
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure
import numpy as np
def solveMBK(inlist):
x0 = inlist[0]
dx0 = inlist[1]
dt = inlist[2]
m = inlist[3]
b = inlist[4]
k = inlist[5]
tf = inlist[6]
Z = inlist[7]
t = np.arange(0,tf,dt)
z0 = np.zeros_like(t)
z1 = np.zeros_like(t)
z0[0] = x0
z1[0] = dx0
for c in range(len(t)-1):
z0[c+1] = z0[c] + z1[c]*dt
z1[c+1] = z1[c] + ((ABradiobutton(Z,t[c]) - k*z0[c] - b*z1[c]) / m)
x = z0
return t,x
def ABradiobutton(Z, t):
if Z == 1:
A = float(A_entry.get())
return A
elif Z == 2:
B = float(B_entry.get())
return np.sin(B*t)
def PlotWindow():
root1 = tk.Tk()
root1.title("Plot")
Mmin = float(Mmin_entry.get())
Mmax = float(Mmax_entry.get())
bmin = float(bmin_entry.get())
bmax = float(bmax_entry.get())
kmin = float(kmin_entry.get())
kmax = float(kmax_entry.get())
mscale = tk.Scale(root1, from_=Mmin, to=Mmax, label="m", bd=2, length=200, orient=tk.HORIZONTAL, command = funcPlot)
mscale.set((Mmin+Mmax)/2)
mscale.grid(row=1, column=0)
bscale = tk.Scale(root1, from_=bmin, to=bmax, label="b", bd=2, length=200, orient=tk.HORIZONTAL, command = funcPlot)
bscale.set((bmin+bmax)/2)
bscale.grid(row=3, column=0)
kscale = tk.Scale(root1, from_=kmin, to=kmax, label="k", bd=2, length=200, orient=tk.HORIZONTAL, command = funcPlot)
kscale.set((kmin+kmax)/2)
kscale.grid(row=5, column=0)
tk.Label(root1, text = " ").grid(row=6, column=0)
tk.Button(root1, text="Back", command=root1.destroy).grid(row=7, column=0)
Graph_Frame = tk.Frame(root1)
Graph_Frame.grid(row=2, column=2, columnspan=10, rowspan=10)
Fig = Figure(figsize=(5.5,4))
a = Fig.add_subplot(111)
if Radio_Var == 1:
t,x = solveMBK(str(mscale.get()), str(bscale.get()), str(kscale.get()), str(A_entry.get()), str(x0_Entry.get()), str(dxdt_Entry.get()), str(tfinal_entry.get()), str(dt_entry.get()))
a.plot(t,x)
# elif Radio_Var == 2:
# t,x = solveMBK()
# a.plot(t,x)
tk.Label(Graph_Frame, text = "Mass-Spring-Damper Plot").pack()
canvas = FigureCanvasTkAgg(Fig, Graph_Frame)
canvas.draw()
canvas.get_tk_widget().pack()
toolbar = NavigationToolbar2Tk(canvas, Graph_Frame)
toolbar.update()
canvas.get_tk_widget().pack()
def CloseWindow():
root.quit()
root.destroy()
exit()
def funcPlot(input_list, mscale, bscale, kscale, a, canvas, event=None):
input_list[0]=float(x0_Entry.get())
input_list[1]=float(dxdt_Entry.get())
input_list[2]=float(dt_entry.get())
input_list[3]=float(mscale.get())
input_list[4]=float(bscale.get())
input_list[5]=float(kscale.get())
input_list[6]=float(tfinal_entry.get())
input_list[7]=float(Radio_Var.get())
data = solveMBK(input_list)
a.plot(data[0], data[1])
canvas.draw()
return
root = tk.Tk()
root.title("Numerical solution of a second order differential equation")
tk.Label(root, text = "Differential Equation:").grid(row=0, column=0, sticky=tk.E)
tk.Label(root, text = "m d2x/dt2 + b dx/dt + kx = f(x)").grid(row=0, column=1)
x0_Start = tk.IntVar()
x0_Start.set("0")
x0_Entry = tk.Entry(root, width=7, textvariable = x0_Start)
tk.Label(root, text = "x(0) = ").grid(row=1, column=0, stick=tk.E), x0_Entry.grid(row=1, column=1, sticky=tk.W)
dxdt_Start = tk.IntVar()
dxdt_Start.set("0")
dxdt_Entry = tk.Entry(root, width=7, textvariable = dxdt_Start)
tk.Label(root, text = "dx(0)/dt= ").grid(row=2, column=0, sticky=tk.E), dxdt_Entry.grid(row=2, column=1, sticky=tk.W)
A_start = tk.IntVar()
A_start.set("1")
A_entry = tk.Entry(root, width=7, textvariable = A_start)
tk.Label(root, text = "A = ").grid(row=6, column=1, sticky=tk.E), A_entry.grid(row=6, column=2, sticky=tk.W)
B_start = tk.IntVar()
B_start.set("0")
B_entry = tk.Entry(root, width=7, textvariable=B_start)
tk.Label(root, text= "B =").grid(row=7,column=1, sticky=tk.E), B_entry.grid(row=7, column=2, sticky=tk.W)
tk.Label(root, text = " ").grid(row=5, column=0, sticky=tk.E)
Radio_Var = tk.IntVar()
tk.Radiobutton(root, text="A", value = 1, variable=Radio_Var).grid(row=6, column=1, sticky = tk.W)
tk.Radiobutton(root, text="sin(Bt)", value = 2, variable=Radio_Var).grid(row=7, column=1, sticky = tk.W)
Radio_Var.set(1)
tk.Label(root, text = "f(x) = ").grid(row=6, column=0, sticky=tk.E)
tk.Label(root, text = " ").grid(row=8, column=0, sticky=tk.E)
tfinal_start = tk.IntVar()
tfinal_start.set("10")
tfinal_entry = tk.Entry(root, width = 7, textvariable=tfinal_start)
tk.Label(root, text = "tfinal = ").grid(row=9, column=0, sticky=tk.E), tfinal_entry.grid(row=9, column=1, sticky=tk.W)
dt_start = tk.IntVar()
dt_start.set("0.001")
dt_entry = tk.Entry(root, width = 7, textvariable=dt_start)
tk.Label(root, text = "dt = ").grid(row=9, column=1, sticky=tk.E), dt_entry.grid(row=9, column=2, sticky=tk.W)
tk.Label(root, text = " ").grid(row=10, column=0, sticky=tk.E)
Mmin_start = tk.IntVar()
Mmin_start.set("1")
Mmin_entry = tk.Entry(root, width=7, textvariable=Mmin_start)
tk.Label(root, text = "Mmin = ").grid(row=11, column=0, sticky=tk.E), Mmin_entry.grid(row=11, column=1, sticky=tk.W)
Mmax_start = tk.IntVar()
Mmax_start.set("100")
Mmax_entry = tk.Entry(root, width=7, textvariable=Mmax_start)
tk.Label(root, text = "Mmax = ").grid(row=11,column=1, sticky=tk.E), Mmax_entry.grid(row=11, column=2, sticky=tk.W)
bmin_start = tk.IntVar()
bmin_start.set("1")
bmin_entry = tk.Entry(root, width=7, textvariable=bmin_start)
tk.Label(root, text = "bmin = ").grid(row=12, column=0, sticky=tk.E), bmin_entry.grid(row=12, column=1, sticky=tk.W)
bmax_start = tk.IntVar()
bmax_start.set("250")
bmax_entry = tk.Entry(root, width=7, textvariable=bmax_start)
tk.Label(root, text= "bmax = ").grid(row=12, column=1, sticky=tk.E), bmax_entry.grid(row=12,column=2,sticky=tk.W)
kmin_start = tk.IntVar()
kmin_start.set("1")
kmin_entry = tk.Entry(root, width=7, textvariable=kmin_start)
tk.Label(root, text= "kmin = ").grid(row=13, column=0, sticky=tk.E), kmin_entry.grid(row=13, column=1, sticky=tk.W)
kmax_start = tk.IntVar()
kmax_start.set("500")
kmax_entry = tk.Entry(root, width=7, textvariable=kmax_start)
tk.Label(root, text="kmax = ").grid(row=13, column=1, sticky=tk.E), kmax_entry.grid(row=13, column=2, sticky=tk.W)
tk.Button(root, text = "Quit", command=CloseWindow, width=10).grid(row=14, column=0)
tk.Button(root, text= "Plot", command=PlotWindow, width=10).grid(row=14, column=3)
root.mainloop()
任何帮助将不胜感激,谢谢!
答案 0 :(得分:0)
您正在将funcPlot
作为command
传递给Scale
进行呼叫:
mscale = tk.Scale(root1, ..., command=funcPlot)
根据文档,command
为:
每次移动滑块时都要调用的过程。这个 过程将被传递 one 参数,即新的小数位值。
但是您的funcPlot()
函数需要使用六个参数,而不是使用一个参数:
def funcPlot(input_list, mscale, bscale, kscale, a, canvas, event=None):
哪个会导致错误:
TypeError: funcPlot() missing 5 required positional arguments: 'mscale', 'bscale', 'kscale', 'a', and 'canvas'
您需要重新考虑它应该如何工作。以下是我对您的代码的重做。我通过使用全局变量解决了上述问题,对此我并不感到骄傲。我还不得不重新设计您的情节嵌入Tk的方式,因为您当时无法使用:
import tkinter as tk
import numpy as np
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure
def solveMBK(inlist):
x0, dx0, dt, m, b, k, tf, Z = inlist
t = np.arange(0, tf, dt)
z0 = np.zeros_like(t)
z1 = np.zeros_like(t)
z0[0] = x0
z1[0] = dx0
for c in range(len(t) - 1):
z0[c + 1] = z0[c] + z1[c] * dt
z1[c + 1] = z1[c] + ((ABradiobutton(Z, t[c]) - k * z0[c] - b * z1[c]) / m)
return t, z0
def ABradiobutton(Z, t):
if Z == 1:
A = float(A_entry.get())
return A
if Z == 2:
B = float(B_entry.get())
return np.sin(B * t)
def PlotWindow():
global mscale, bscale, kscale, subplot, figure_canvas
plot_window = tk.Toplevel(root)
plot_window.title("Plot")
Mmin = float(Mmin_entry.get())
Mmax = float(Mmax_entry.get())
bmin = float(bmin_entry.get())
bmax = float(bmax_entry.get())
kmin = float(kmin_entry.get())
kmax = float(kmax_entry.get())
mscale = tk.Scale(plot_window, from_=Mmin, to=Mmax, label="m", bd=2, length=200, orient=tk.HORIZONTAL, command=funcPlot)
mscale.set((Mmin + Mmax) / 2)
mscale.grid(row=1, column=0)
bscale = tk.Scale(plot_window, from_=bmin, to=bmax, label="b", bd=2, length=200, orient=tk.HORIZONTAL, command=funcPlot)
bscale.set((bmin + bmax) / 2)
bscale.grid(row=3, column=0)
kscale = tk.Scale(plot_window, from_=kmin, to=kmax, label="k", bd=2, length=200, orient=tk.HORIZONTAL, command=funcPlot)
kscale.set((kmin + kmax) / 2)
kscale.grid(row=5, column=0)
tk.Label(plot_window, text=" ").grid(row=6, column=0)
tk.Button(plot_window, text="Back", command=plot_window.destroy).grid(row=7, column=0)
graph_frame = tk.Frame(plot_window)
graph_frame.grid(row=2, column=2, columnspan=10, rowspan=10)
figure = Figure(figsize=(5.5, 4))
subplot = figure.add_subplot(111)
if Radio_Var.get() == 1:
t, x = solveMBK([float(mscale.get()), float(bscale.get()), float(kscale.get()), float(A_entry.get()), float(x0_Entry.get()), float(dxdt_Entry.get()), float(tfinal_entry.get()), float(dt_entry.get())])
subplot.plot(t, x)
# elif Radio_Var.get() == 2:
# t, x = solveMBK()
# subplot.plot(t, x)
figure_canvas = FigureCanvasTkAgg(figure, master=graph_frame)
figure_canvas.draw()
figure_canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
toolbar = NavigationToolbar2Tk(figure_canvas, graph_frame)
toolbar.update()
figure_canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
tk.Label(graph_frame, text="Mass-Spring-Damper Plot").pack()
def CloseWindow():
root.quit()
root.destroy()
exit()
def funcPlot(event):
input_list = []
input_list.append(float(x0_Entry.get()))
input_list.append(float(dxdt_Entry.get()))
input_list.append(float(dt_entry.get()))
input_list.append(float(mscale.get()))
input_list.append(float(bscale.get()))
input_list.append(float(kscale.get()))
input_list.append(float(tfinal_entry.get()))
input_list.append(float(Radio_Var.get()))
t, x = solveMBK(input_list)
subplot.plot(t, x)
figure_canvas.draw()
figure_canvas = subplot = mscale = bscale = kscale = None
root = tk.Tk()
root.title("Numerical solution of a second order differential equation")
tk.Label(root, text="Differential Equation:").grid(row=0, column=0, sticky=tk.E)
tk.Label(root, text="m d2x/dt2 + b dx/dt + kx = f(x)").grid(row=0, column=1)
tk.Label(root, text="x(0) = ").grid(row=1, column=0, stick=tk.E)
x0_Start = tk.IntVar()
x0_Start.set("0")
x0_Entry = tk.Entry(root, width=7, textvariable=x0_Start)
x0_Entry.grid(row=1, column=1, sticky=tk.W)
tk.Label(root, text="dx(0)/dt = ").grid(row=2, column=0, sticky=tk.E)
dxdt_Start = tk.IntVar()
dxdt_Start.set("0")
dxdt_Entry = tk.Entry(root, width=7, textvariable=dxdt_Start)
dxdt_Entry.grid(row=2, column=1, sticky=tk.W)
tk.Label(root, text=" ").grid(row=5, column=0, sticky=tk.E)
Radio_Var = tk.IntVar()
Radio_Var.set(1)
tk.Label(root, text="f(x) = ").grid(row=6, column=0, sticky=tk.E)
tk.Radiobutton(root, text="A", value=1, variable=Radio_Var).grid(row=6, column=1, sticky=tk.W)
tk.Label(root, text="A = ").grid(row=6, column=1, sticky=tk.E)
A_start = tk.IntVar()
A_start.set("1")
A_entry = tk.Entry(root, width=7, textvariable=A_start)
A_entry.grid(row=6, column=2, sticky=tk.W)
tk.Radiobutton(root, text="sin(Bt)", value=2, variable=Radio_Var).grid(row=7, column=1, sticky=tk.W)
tk.Label(root, text="B =").grid(row=7, column=1, sticky=tk.E)
B_start = tk.IntVar()
B_start.set("0")
B_entry = tk.Entry(root, width=7, textvariable=B_start)
B_entry.grid(row=7, column=2, sticky=tk.W)
tk.Label(root, text=" ").grid(row=8, column=0, sticky=tk.E)
tk.Label(root, text="tfinal = ").grid(row=9, column=0, sticky=tk.E)
tfinal_start = tk.IntVar()
tfinal_start.set("10")
tfinal_entry = tk.Entry(root, width=7, textvariable=tfinal_start)
tfinal_entry.grid(row=9, column=1, sticky=tk.W)
tk.Label(root, text="dt = ").grid(row=9, column=1, sticky=tk.E)
dt_start = tk.IntVar()
dt_start.set("0.001")
dt_entry = tk.Entry(root, width=7, textvariable=dt_start)
dt_entry.grid(row=9, column=2, sticky=tk.W)
tk.Label(root, text=" ").grid(row=10, column=0, sticky=tk.E)
tk.Label(root, text="Mmin = ").grid(row=11, column=0, sticky=tk.E)
Mmin_start = tk.IntVar()
Mmin_start.set("1")
Mmin_entry = tk.Entry(root, width=7, textvariable=Mmin_start)
Mmin_entry.grid(row=11, column=1, sticky=tk.W)
tk.Label(root, text="Mmax = ").grid(row=11, column=1, sticky=tk.E)
Mmax_start = tk.IntVar()
Mmax_start.set("100")
Mmax_entry = tk.Entry(root, width=7, textvariable=Mmax_start)
Mmax_entry.grid(row=11, column=2, sticky=tk.W)
tk.Label(root, text="bmin = ").grid(row=12, column=0, sticky=tk.E)
bmin_start = tk.IntVar()
bmin_start.set("1")
bmin_entry = tk.Entry(root, width=7, textvariable=bmin_start)
bmin_entry.grid(row=12, column=1, sticky=tk.W)
tk.Label(root, text="bmax = ").grid(row=12, column=1, sticky=tk.E)
bmax_start = tk.IntVar()
bmax_start.set("250")
bmax_entry = tk.Entry(root, width=7, textvariable=bmax_start)
bmax_entry.grid(row=12, column=2, sticky=tk.W)
tk.Label(root, text="kmin = ").grid(row=13, column=0, sticky=tk.E)
kmin_start = tk.IntVar()
kmin_start.set("1")
kmin_entry = tk.Entry(root, width=7, textvariable=kmin_start)
kmin_entry.grid(row=13, column=1, sticky=tk.W)
tk.Label(root, text="kmax = ").grid(row=13, column=1, sticky=tk.E)
kmax_start = tk.IntVar()
kmax_start.set("500")
kmax_entry = tk.Entry(root, width=7, textvariable=kmax_start)
kmax_entry.grid(row=13, column=2, sticky=tk.W)
tk.Button(root, text="Quit", command=CloseWindow, width=10).grid(row=14, column=0)
tk.Button(root, text="Plot", command=PlotWindow, width=10).grid(row=14, column=3)
root.mainloop()