简体   繁体   English

python谐波运动动画

[英]harmonic motion animation with python

I am trying to plot an animation of a simple pendulum using the model https://matplotlib.org/gallery/animation/double_pendulum_sgskip.html . 我正在尝试使用模型https://matplotlib.org/gallery/animation/double_pendulum_sgskip.html绘制简单摆的动画。

My code is as follows : 我的代码如下:

from numpy import sin, cos
import numpy as np
import matplotlib.pyplot as plt
import scipy.integrate as integrate
import matplotlib.animation as animation

#some constants 
g = 9.81 
l = 0.1 
m = 0.01 

def sh(r,t):
    theta = r[0]
    omega = r[1]
    sh_theta = omega
    sh_omega = -g/l*sin(theta) 
    return np.array([sh_theta,sh_omega],float)

init_state = [np.radians(89.0),0]
time = np.arange(0,50.0,0.025)
time_elapsed = time

def step_solver(eq, ist, dt):

    """
    Execute one time step of length dt and update status

    """
    global time_elapsed 

    state1,state2 = integrate.odeint(eq,ist,[0,dt])
    time_elapsed += dt

    return state1, state2,time_elapsed
dt = 1/30
ysol,ysolv,timex = step_solver(sh,init_state,dt)
print("This is the y0 values: ", ysol,"y values",ysolv,"This is the time ", timex) 

##===================================
##Setting up figure and animation 
#======================================
fig = plt.figure()
ax = plt.axes(xlim = (0,2), ylim = (-2,2))
line, = ax.plot([],[],lw=2)
#time_text = ax.text(0.02,0.95,'',transform = ax.transAxes) 
#==========================================
##initialisation function: plot the background of each frame 
def init():
    line.set_data([],[])
    #time_text.set_text('')
    return line, 

def animate(ysol,timex):

    x = timex 
    y = ysol

    line.set_data(x,y)
    #time_text.set_text(str(i))
    return line,
#================================================
#Call the animator    
#================================================
anim = animation.FuncAnimation(fig,animate(ysolv,timex), init_func = init, frames = 200, interval =20, blit = True)
anim.save('basic_animation.mp4', fps=30, extra_args=['-vcodec', 'libx264'])
plt.show()

EDIT : I am getting the error message : 编辑:我收到错误消息:

  ValueError: shape mismatch: objects cannot be broadcast to a single shape

  <Figure size 432x288 with 1 Axes>

I have checked what my function step_solver is printing with 我检查了我的函数step_solver正在打印什么

 print(len(ysol),len(ysolv),len(timex))

and after recommendation the other y output for odeint which gave only 2 values for my ysol and ysolv variable for 2200 time values. 在推荐之后,另一个odeint的y输出为我的ysol和ysolv变量提供了2个时间值,仅给出2个值。

I was expecting to get a range of y values for each time step. 我期望每个时间步长都能得到y值范围。 I am not sure how to sort this. 我不确定如何排序。 Is my function step_solver wrongly coded? 我的函数step_solver是否编码错误? Why am I only getting 2 values, how can I animate the solution in the same way it was done for the double pendulum? 为什么我只得到2个值,如何以与双摆相同的方式为解决方案制作动画?

Any suggestions on where the problem may lie? 关于问题可能出在哪里的任何建议? Many thanks in advance. 提前谢谢了。

Let's follow the code from the example more closely. 让我们更密切地关注示例中的代码。 Which means to use just one integration call and then using slices of the result of that call in the animation. 这意味着只使用一个积分调用,然后在动画中使用该调用结果的切片。

from numpy import sin, cos
import numpy as np
import matplotlib.pyplot as plt
import scipy.integrate as integrate
import matplotlib.animation as animation

#some constants 
g = 9.81 
l = 0.1 
m = 0.01 

def sh(r,t):
    theta, omega = r
    sh_theta = omega
    sh_omega = -g/l*sin(theta) 
    return np.array([sh_theta,sh_omega],float)

init_state = np.radians([89.0,0])
dt = 1.0/30
time = np.arange(0,50.0,dt)

state = integrate.odeint(sh,init_state,time)

##===================================
##Setting up figure and animation 
#======================================
fig = plt.figure()
ax = plt.axes(xlim = (0,10), ylim = (-2,2))
line, = ax.plot([],[],lw=2)
#==========================================
##initialisation function: plot the background of each frame 
def init():
    return line, 

def animate(i):

    x = time[i:i+30] 
    y = state[i:i+30,0]

    line.set_data(x,y)
    return line,
#================================================
#Call the animator    
#================================================
anim = animation.FuncAnimation(fig,animate, init_func = init, frames = 200, interval =20, blit = True)
plt.show()

For a variant using a step generator using yield see my answer in Error in RK4 algorithm in Python . 对于使用使用yield的step generator的变体,请参阅我在Python的RK4算法中的Error中的答案。 This allows to encapsulate the data for the integration loop without defining a class for it. 这允许为集成循环封装数据,而无需为其定义类。 However it is not clear how a function graph with two samples would be helpful, even if it is animated. 但是,尚不清楚具有两个样本的功能图是否有帮助,即使它是动画的也是如此。

To animate the pendulum itself, use 要为摆锤本身制作动画,请使用

##===================================
##Setting up figure and animation 
#======================================
fig = plt.figure(figsize=(8,6))
ax = plt.axes(xlim = (-2*l,2*l), ylim = (-2*l,l))
line, = ax.plot([],[],'-o',lw=2,ms=8)
#==========================================
##initialisation function: plot the background of each frame 
def init():
    return line, 

def animate(i):

    phi = state[i,0]

    line.set_data([0,l*sin(phi)],[0,-l*cos(phi)])
    return line,
#================================================
#Call the animator    
#================================================
anim = animation.FuncAnimation(fig,animate, init_func = init, frames = len(time), interval =100, blit = True)
plt.show()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM