I would like to plot an animated vibrating string using python but to be able to play it and to control the parameters used during the vibration (much like this Desmos calculation). So far, this is my code:
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
I can control the wavefunction and all parameters, but I am not sure about what is the easiest way to animate it.
So far, I know that matplotlib can do it, but I am wondering if we have a more straightforward way to do animated interactive plots (using another package, maybe?).
Thanks in advance for any help.
Here my version of your script useing opencv and numpy.
You can set all params in realtime using keyboard. More info in the code
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()