1

我想使用 python 绘制一个动画振动字符串,但能够播放它并控制振动期间使用的参数(很像这个 Desmos 计算)。到目前为止,这是我的代码:

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 可以做到这一点,但我想知道我们是否有更直接的方法来制作动画交互式绘图(也许使用另一个包?)。

提前感谢您的帮助。

4

3 回答 3

0

看一下gif python 包。我只将它用于简单的 gif 保存。但它可以与 plotly 或 Altair 集成,这可能会提供更好的交互。

于 2021-03-30T23:47:57.013 回答
0

这是我刚刚根据这个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()

一 二 三 四

于 2021-04-05T06:42:39.870 回答
0

这是我使用 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() 
于 2021-04-04T22:02:04.613 回答