【问题标题】:Refresh Animated Plot with Tkinter Scale Widget使用 Tkinter Scale 小部件刷新动画图
【发布时间】:2020-08-25 22:57:26
【问题描述】:

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

这个项目并不是真正的驻波模拟,因为我没有在数值上求解具有必要边界条件的波动方程;相反,我正在生成一个入射正弦波和一个“反射”正弦波。在这里,可以调整入射波,使两个波之间的波矢量匹配,从而产生驻波。我的目标是能够通过 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 很陌生,所以我可能只是遗漏了一些明显的东西。

【问题讨论】:

  • 因为你已经有一个动画在运行,你实际上不需要做任何事情来响应滑块的移动。只需在 animate() 函数中获取当前滑块值,并在更新计算中适当使用它。请注意,为了做到这一点,您需要一个名称来引用滑块。 horizontal 当前只是 None,是 .grid() 调用的结果,而不是小部件本身。
  • 非常感谢,效果很好!比我担心的解决方案要简单得多。

标签: python numpy tkinter matplotlib-animation


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多