阻尼振荡器弹簧

时间:2021-05-17 04:29:54

标签: python matplotlib animation

美好的一天!我期待增强阻尼振荡程序的动画,但我不知道如何将蓝线延伸到第一个子图的左侧部分,以便盒子回到与下图相同的平衡位置。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation


#Ask user to input parameters
w = np.pi
b = np.pi*0.2

#Function that implements rk4 integration
def rk4(t, x, f, dt):
    dx1 = f(t, x)*dt
    dx2 = f(t+0.5*dt, x+0.5*dx1)*dt
    dx3 = f(t+0.5*dt, x+0.5*dx2)*dt
    dx4 = f(t+dt, x+dx3)*dt
    return x+dx1/6.0+dx2/3.0+dx3/3.0+dx4/6.0

#Function that returns dX/dt for the linearly damped oscillator
def dXdt(t, X):
    x = X[0]
    vx = X[1]
    ax = -2*b*vx - w**2*x
    return np.array([vx, ax])

#Initialize Variables
x0 = 5.0 #Initial x position
vx0 = 1.0 #Initial x Velocity

#Setting time array for graph visualization (for the first 10 seconds)
dt = 0.01
N = 1000
x = np.zeros(N)
vx = np.zeros(N)
y = []

# integrate equations of motion using rk4;
# X is a vector that contains the positions and velocities being integrated
X = np.array([x0, vx0])
t = np.arange(0, dt*N, dt)
for i in range(N):
    x[i] = X[0]
    vx[i] = X[1]
    y.append(0)
    # update the vector X to the next time step
    X = rk4(i*dt, X, dXdt, dt)

#Ploting the results in with 3 rows and 1 colum (1 plot each row)
fig, (ax1, ax2, ax3) = plt.subplots(3,1, figsize=(10,10))
fig.suptitle(r' Damped Oscillation with $\beta$$\approx$' + str(round(b,2)) + r' and $\omega$$\approx$'
             + str(round(w,2)), fontsize=16)

#Simulation
line1, = ax1.plot([], [], lw=10,c="blue",ls="-",ms=50,marker="s",mfc="gray",fillstyle="none",mec="black",markevery=2)
time_template = '\nTime = %.1fs'
time_text = ax1.text(0.1, 0.9, '', transform=ax1.transAxes)
line5,=ax1.plot([],[],lw=2,c="black",marker="^")

#Position and Velocity Time graph on twin axis
line2, = ax2.plot([], [], lw=2, color='g', label='x')
line4, = ax2.plot([], [], lw=2, color='m', label= r'$\dot{x}$')

#Phase Path
line3, = ax3.plot([], [], lw=2, color='r')


#Marker


#Setting limits for the axes by scaling a bit for nice visualiztion
for ax in [ax1, ax2, ax3]:
    #For the visualization
    ax1.set_xlim(1.2*min(x), 1.2*max(x))
    #For the position and velocity time graph
    ax2.set_ylim(1.4*min(vx), 1.4*max(x)) #
    ax2.set_xlim(0, N*dt) #
    #For the phase path
    ax3.set_ylim(1.2*min(vx), 1.2*max(vx))
    ax3.set_xlim(1.2*min(x), 1.2*max(x))

#Animating the results
def init():
    line1.set_data([], [])
    line2.set_data([], [])
    line3.set_data([], [])
    line4.set_data([], [])
    time_text.set_text('')
    return line1, line2, line3, line4, time_text

#Function adding each ith coordinate element in the graph to appropriate data points
def animate(i):
    line1.set_data([x[i],0], [y[i],0]) 
    line2.set_data(t[:i], x[:i])
    line3.set_data(x[:i], vx[:i])
    line4.set_data(t[:i], vx[:i])
    line5.set_data([0.0,0.0],[-0.4,-0.03])
    time_text.set_text(time_template % (i*dt))
    return line1, line2, line3, line4, time_text  

#Call the FuncAnimation to animate
ani = animation.FuncAnimation(fig, animate, len(t),
                              interval=10, blit=True, init_func=init,repeat=False)

#Plotting and identifying axis labels
fig.tight_layout(pad=5.0)
ax1.set_xlabel('x (m)', fontsize=12)
ax2.set_xlabel('t (s)', fontsize=12)
ax2.set_ylabel(r'x , $\dot{x}$', fontsize=12)
ax3.set_xlabel('x (m)', fontsize=12)
ax3.set_ylabel(r'$\dot{x}$ (m/s)', fontsize=12)
ax1.set_title("Visualization", fontsize=12)
ax2.set_title("Position and Velocity Time Graph", fontsize=12)
ax2.legend()
ax3.set_title("Phase Path", fontsize=12)

所需的输出:Photo

我还包含了一个链接,其中的输出应该类似于 Link

1 个答案:

答案 0 :(得分:0)

您之前的代码应该只是通过偏移弹簧左侧的 x 位置来更新。为此,您可以指定静止弹簧的长度,例如 L = 5.,它给出:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation


#Constants
w = np.pi #angular frequency
b = np.pi * 0.2  #damping parameter

# length of the spring at rest (>0)
L = 5.

#Function that implements rk4 integration
def rk4(t, x, f, dt):
    dx1 = f(t, x)*dt
    dx2 = f(t+0.5*dt, x+0.5*dx1)*dt
    dx3 = f(t+0.5*dt, x+0.5*dx2)*dt
    dx4 = f(t+dt, x+dx3)*dt
    return x+dx1/6.0+dx2/3.0+dx3/3.0+dx4/6.0

#Function that returns dX/dt for the linearly damped oscillator
def dXdt(t, X):
    x = X[0]
    vx = X[1]
    ax = -2*b*vx - w**2*x
    return np.array([vx, ax])

#Initialize Variables
x0 = 5.0 #Initial x position
vx0 = 1.0 #Initial x Velocity

#Setting time array for graph visualization
dt = 0.05
N = 200
t = np.linspace(0,N*dt,N,endpoint=False)
x = np.zeros(N)
vx = np.zeros(N)
y = np.zeros(N)
# integrate equations of motion using rk4;
# X is a vector that contains the positions and velocities being integrated
X = np.array([x0, vx0])

for i in range(N):
    x[i] = X[0]
    vx[i] = X[1]
    # update the vector X to the next time step
    X = rk4(i*dt, X, dXdt, dt)

fig, (ax1, ax2, ax3) = plt.subplots(3,1, figsize=(8,12))
fig.suptitle(r' Damped Oscillation with $\beta$$\approx$' + str(round(b,2)) + r' and $\omega$$\approx$'
             + str(round(w,2)), fontsize=16)
line1, = ax1.plot([], [], lw=10,c="blue",ls="-",ms=50,marker="s",mfc="gray",fillstyle="none",mec="black",markevery=2)
line2, = ax2.plot([], [], lw=1, color='r')
line3, = ax3.plot([], [], lw=1, color='g')
time_template = '\nTime = %.1fs'
time_text = ax1.text(0.2, 0.9, '', transform=ax1.transAxes)


ax1.set_xlim(-delta_x-1, 1.2*max(x))
ax1.plot([-L,-L],[-0.04,0.04],color='black',lw=10)
ax1.plot([-L,-L],[-0.04,0.04],'k--')
ax1.plot([x0,x0],[-0.04,0.04],'k--') # initial condition
ax1.plot([0,0],[-0.04,0.04],'k--') # rest
ax1.set_xlabel('x')
ax1.set_ylabel('y')

ax2.set_ylim(1.2*min(x), 1.2*max(x),1)
ax2.set_xlim(0, N*dt)
ax2.set_xlabel('t')
ax2.set_ylabel('x')

ax3.set_xlim(1.2*min(x), 1.2*max(x),1)
ax3.set_ylim(1.2*min(vx), 1.2*max(vx),1)
ax3.set_xlabel('x')
ax3.set_ylabel('vx')

def init():
    line1.set_data([], [])
    line2.set_data([], [])
    line3.set_data([], [])
    time_text.set_text('')
    return line1, line2, line3, time_text

def animate(i):
    line1.set_data([x[i],-L], [y[i],0])
    line2.set_data(t[:i], x[:i])
    line3.set_data(x[:i], vx[:i])
    time_text.set_text(time_template % (i*dt))
    return line1, line2, line3, time_text  

ani = animation.FuncAnimation(fig, animate, np.arange(1, N),
                              interval=50, blit=True, init_func=init,repeat=False)

ani.save('anim.gif')

现在给出:

anim.gif