使用 Tkinter Scale 小部件刷新动画图

Refresh Animated Plot with Tkinter Scale Widget

我正在制作一个交互式伪驻波演示,但我有点陷入僵局。从本质上讲,该项目的目标是重新创建 Melde 实验的一个变体,其中一根绳子的一端由振荡器驱动,另一端以 90 度角连接到滑轮。在这个实验的物理版本中,人们会在这个滑轮上悬挂的杯子中加入铅丸,增加绳子的张力,直到形成驻波。

这个项目并不是真正的驻波模拟,因为我没有用必要的边界条件数值求解波动方程;相反,我正在生成一个入射正弦波和一个 'reflected' 正弦波。在这里,可以调整入射波,使两个波之间的波矢量匹配,从而产生驻波。我的目标是能够通过 Tkinter 的比例小部件调整落入杯中的铅弹丸的数量来调整此波。换句话说,我希望能够调整下面屏幕截图中显示的滑块并相应地更新(动画)波形。

我在这个论坛上发现了一些有些相关的问题,但它们似乎都与通过滑块的移动更新静止图或动画滑块本身有关。在我的例子中,波浪图已经是动画了——已经在时间上移动了,我想在滑块被调整时刷新动画本身。我知道我需要命令缩放小部件调用函数,但我不确定如何在保留代码中已经存在的动画函数的同时执行此操作。最终,我希望能够使用比例小部件控制参数 N(朝向下面代码的顶部),并相应地更新动画图。

import matplotlib.pylab as plot
import numpy as np
import matplotlib.animation as animation
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk

h = 3                           #define nth harmonic
kval = np.pi*h/100              #wave vector from nth harmonic (1/cm)
mu = 0.001                      #linear string mass density (g/cm)
g = 980                         #gravitational acceleration (cm/s/s)
N = 50                          #number of lead shot pellets
m = N*0.01216                   #total mass of lead shot pellets (g)
A = 0.15                        #wave amplitude
omega = 120                     #angular wave frequency
k1 = omega*np.sqrt(mu/(m*g))    #wave vector for initial wave (1/cm)
k2 = k1*k1/kval                 #wave vector for 'reflected' wave (1/cm)

fig = plot.Figure()

x = np.linspace(0,100,500)

def animate(i):
    line.set_ydata(A*np.sin(k1*x+omega*i) + A*np.sin(k2*x - omega*i))
    return line,

main = tk.Tk()

#background text
intro = tk.Label(main,text='Add lead shot to produce a standing wave.').grid(column=0,row=0)

canvas = FigureCanvasTkAgg(fig, master=main)
canvas.get_tk_widget().grid(column=0,row=1)

ax = fig.add_subplot(111)
ax.set_xlim(0,100)
ax.set_ylim(-2,2)

line, = ax.plot(x, A*np.sin(k1*x) + A*np.sin(k2*x))
anim = animation.FuncAnimation(fig, animate, interval=50, blit=False)

horizontal = tk.Scale(main, from_=50, to=300, length=400, orient='horizontal').grid(column=0,row=2)

main.mainloop()

非常感谢任何建议!我是使用 Tkinter 的新手,所以我可能只是遗漏了一些明显的东西。

正如用户 jasonharper 所述,只需在动画函数中获取当前滑块值即可完美运行。