使用 python 的动画交互式振动弦
Animated interactive vibrating string using python
我想使用 python 绘制动画振动弦,但为了能够播放它并控制振动期间使用的参数 (much like this Desmos calculation)。
到目前为止,这是我的代码:
from __future__ import print_function
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets
import matplotlib as mpl
%matplotlib inline
def f(n=1, v=0.2, L=2, t=0):
x = np.linspace(0, L, 2001)
func = np.sin((n*np.pi*x)/L)*np.cos((n*np.pi*v*t)/L)
plt.figure(figsize=(6,6))
ax1 = plt.plot(x, func)
plt.show()
interactive_plot = interactive(f, n=(0, 10, 1), v=(0.2, 5, 0.1), L=(0.2, 2, 0.1), t=(0, 10, 1))
output = interactive_plot.children[-1]
interactive_plot
我可以控制波函数和所有参数,但我不确定最简单的动画方法是什么。
到目前为止,我知道 matplotlib 可以做到,但我想知道我们是否有更直接的方法来制作动画交互式绘图(也许使用另一个包?)。
在此先感谢您的帮助。
看看 gif python 包。我只将它用于简单的 gif 保存。但是可以和plotly或者Altair集成,这样可能会有更好的交互。
这是我使用 opencv 和 numpy 的脚本版本。
您可以使用键盘实时设置所有参数。
代码中有更多信息
import numpy as np
import cv2
def f(im,n=1, v=0.2, L=2, t=0):
x = np.linspace(0, L, 2001)
func = np.sin( (n*np.pi*x) / L ) * np.cos( (n*np.pi*v*t) / L )
ww2 = int(win_w/2)
wh2 = int(win_h/2)
scale = 100
for i in range(len(x)):
ix=x[i]
iy=func[i]
p = (int(ww2 + ix*scale) , int(wh2 + iy*scale))
cv2.circle( im, p ,1, (255,255,255) )
win_w=640
win_h=480
#params={
# "n":(0, 10, 1),
# "v":(0.2, 5, 0.1),
# "L":(0.2, 2, 0.1),
# "t":(0, 10, 1)
#}
params={
"n":[10],
"v":[5],
"L":[2],
"t":[0]
}
while True:
im = np.zeros( (win_h,win_w,3), dtype="uint8")
for i in range(len(params["n"])):
n=params["n"][i]
v=params["v"][i]
L=params["L"][i]
t=params["t"][i]
f(im,n,v,L,t)
cv2.imshow("f",im)
k = cv2.waitKey(33) & 0xFF
if k==ord('q'):break
# Parameter setting with the keyboard
# comment / uncomment this for animation:
params["t"][0]+=.001
# n param setting +,- use n,b
if k==ord('n'): params["n"][0]+=.001
if k==ord('b'): params["n"][0]-=.001
# v param setting +,- use v,c
if k==ord('v'): params["v"][0]+=.001
if k==ord('c'): params["v"][0]-=.001
# L param setting +,- use l,k
if k==ord('l'): params["L"][0]+=.001
if k==ord('k'): params["L"][0]-=.001
# t param setting +,- use t,r
if k==ord('t'): params["t"][0]+=.001
if k==ord('r'): params["t"][0]-=.001
print(params)
cv2.destroyAllWindows()
这是我刚刚根据 this YouTube 视频制作的简单情节。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button
x = np.arange(0,np.pi,0.01)
y_base = 0.5*np.sin(x)
y = y_base+1
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.1, bottom=0.35)
p, = plt.plot(x,y, linewidth=2, color='blue')
plt.axis([0,np.pi,0,2])
axSlider = plt.axes([0.1,0.2,0.8,0.05])
slider1 = Slider(axSlider, "Slider", valmin=-100, valmax=100)
def val_update(val):
yval = slider1.val/50
p.set_ydata(yval*y_base+1)
plt.draw()
slider1.on_changed(val_update)
plt.show()
我想使用 python 绘制动画振动弦,但为了能够播放它并控制振动期间使用的参数 (much like this Desmos calculation)。 到目前为止,这是我的代码:
from __future__ import print_function
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets
import matplotlib as mpl
%matplotlib inline
def f(n=1, v=0.2, L=2, t=0):
x = np.linspace(0, L, 2001)
func = np.sin((n*np.pi*x)/L)*np.cos((n*np.pi*v*t)/L)
plt.figure(figsize=(6,6))
ax1 = plt.plot(x, func)
plt.show()
interactive_plot = interactive(f, n=(0, 10, 1), v=(0.2, 5, 0.1), L=(0.2, 2, 0.1), t=(0, 10, 1))
output = interactive_plot.children[-1]
interactive_plot
我可以控制波函数和所有参数,但我不确定最简单的动画方法是什么。
到目前为止,我知道 matplotlib 可以做到,但我想知道我们是否有更直接的方法来制作动画交互式绘图(也许使用另一个包?)。
在此先感谢您的帮助。
看看 gif python 包。我只将它用于简单的 gif 保存。但是可以和plotly或者Altair集成,这样可能会有更好的交互。
这是我使用 opencv 和 numpy 的脚本版本。
您可以使用键盘实时设置所有参数。 代码中有更多信息
import numpy as np
import cv2
def f(im,n=1, v=0.2, L=2, t=0):
x = np.linspace(0, L, 2001)
func = np.sin( (n*np.pi*x) / L ) * np.cos( (n*np.pi*v*t) / L )
ww2 = int(win_w/2)
wh2 = int(win_h/2)
scale = 100
for i in range(len(x)):
ix=x[i]
iy=func[i]
p = (int(ww2 + ix*scale) , int(wh2 + iy*scale))
cv2.circle( im, p ,1, (255,255,255) )
win_w=640
win_h=480
#params={
# "n":(0, 10, 1),
# "v":(0.2, 5, 0.1),
# "L":(0.2, 2, 0.1),
# "t":(0, 10, 1)
#}
params={
"n":[10],
"v":[5],
"L":[2],
"t":[0]
}
while True:
im = np.zeros( (win_h,win_w,3), dtype="uint8")
for i in range(len(params["n"])):
n=params["n"][i]
v=params["v"][i]
L=params["L"][i]
t=params["t"][i]
f(im,n,v,L,t)
cv2.imshow("f",im)
k = cv2.waitKey(33) & 0xFF
if k==ord('q'):break
# Parameter setting with the keyboard
# comment / uncomment this for animation:
params["t"][0]+=.001
# n param setting +,- use n,b
if k==ord('n'): params["n"][0]+=.001
if k==ord('b'): params["n"][0]-=.001
# v param setting +,- use v,c
if k==ord('v'): params["v"][0]+=.001
if k==ord('c'): params["v"][0]-=.001
# L param setting +,- use l,k
if k==ord('l'): params["L"][0]+=.001
if k==ord('k'): params["L"][0]-=.001
# t param setting +,- use t,r
if k==ord('t'): params["t"][0]+=.001
if k==ord('r'): params["t"][0]-=.001
print(params)
cv2.destroyAllWindows()
这是我刚刚根据 this YouTube 视频制作的简单情节。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button
x = np.arange(0,np.pi,0.01)
y_base = 0.5*np.sin(x)
y = y_base+1
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.1, bottom=0.35)
p, = plt.plot(x,y, linewidth=2, color='blue')
plt.axis([0,np.pi,0,2])
axSlider = plt.axes([0.1,0.2,0.8,0.05])
slider1 = Slider(axSlider, "Slider", valmin=-100, valmax=100)
def val_update(val):
yval = slider1.val/50
p.set_ydata(yval*y_base+1)
plt.draw()
slider1.on_changed(val_update)
plt.show()