【问题标题】:Animated interactive vibrating string using python使用python的动画交互式振动字符串
【发布时间】:2021-03-26 15:56:31
【问题描述】:

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

提前感谢您的帮助。

【问题讨论】:

    标签: python plot matplotlib-animation


    【解决方案1】:

    这是我使用 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() 
    

    【讨论】:

    • 非常感谢@Mario。答案和我想要的很接近,我相信学生们会理解波函数的。谢谢。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-27
        相关资源
        最近更新 更多