隔江千里
我在这个问题上的错误实际上是一个非常基本的错误和对set_data功能的误解。我以为我需要传递一个新的数据点,但实际上你需要传递整个数据集,但要有更新的点。所以,代码最终看起来如下:import numpy as npimport matplotlib.pyplot as pltimport matplotlib.patches as patchesimport matplotlib.gridspec as gridspec # =============================================================================# Parameters# =============================================================================SIM_TIME = 10STEP_SIZE = 0.05steps = int(SIM_TIME/STEP_SIZE)STEPS_PER_FRAME = 4order = 4 # Two second order equations ICs = [0., 0., 0., 1., 0.] # Intial conditions; t0, x1, x1dot, x2, x2dotparameters = {'a':[1.0, 'unit'], 'b':[2.0, 'unit'], 'c':[3.0, 'unit']}# =============================================================================# Intializing Arrays# =============================================================================x_and_v = np.empty(shape=(order, steps)) # Each row is a var, i.e. x1,x2,... # Set initial conditions for each varfor i in range(order): x_and_v[i][0] = ICs[i+1] K = np.empty(shape=(4, order)) # Each row is k1, k2, k3, k4 for each vart = np.empty(steps)t[0] = ICs[0]# =============================================================================# ODE function# =============================================================================def ODE(t, curr): dx1dt = parameters['a'][0]*t dv1dt = parameters['b'][0]*t dx2dt = parameters['a'][0]*t dv2dt = parameters['c'][0]*t return np.array([dx1dt, dv1dt, dx2dt, dv2dt])# =============================================================================# Runge-Kutta (4th Order) Method# =============================================================================def RK4(i): # calculates each k value K[0] = STEP_SIZE * ODE(t[i], x_and_v[:, i]) K[1] = STEP_SIZE * ODE(t[i] + STEP_SIZE/2, x_and_v[:, i] + K[0]/2) K[2] = STEP_SIZE * ODE(t[i] + STEP_SIZE/2, x_and_v[:, i] + K[1]/2) K[3] = STEP_SIZE * ODE(t[i] + STEP_SIZE, x_and_v[:, i] + K[2]) return 1/6 * (K[0] + 2*K[1] + 2*K[2] + K[3])# =============================================================================# Plotting function# =============================================================================plt.close('all')plt.ion()fig = plt.figure(figsize=(10, 12))fig.suptitle(f'Title (stepsize: {STEP_SIZE})', y=0.94)gs = gridspec.GridSpec(2, 2)graph_left = fig.add_subplot(gs[0, 0])graph_right = fig.add_subplot(gs[0, 1], sharey=graph_left)graph_left_x_line, = graph_left.plot(np.array([]), np.array([]), label='Position', color='#1248a1')graph_left_v_line, = graph_left.plot(np.array([]), np.array([]), label='Velocity', color='#77a7f7')graph_left.set_ylabel('position [m]/velocity [m/s]')graph_left.set_xlabel('time [s]')graph_left.legend(loc=2)graph_right_x_line, = graph_right.plot(np.array([]), np.array([]), label='Position', color='#ba7000')graph_right_v_line, = graph_right.plot(np.array([]), np.array([]), label='Velocity', color='#f7c477')graph_right.set_xlabel('time [s]')graph_right.legend(loc=2)block = fig.add_subplot(gs[1, :])block.set_title('Block Animation')block.set_xlabel('Position [m]')def Plotting(i): """Plotting x_and_v with time counter in the top middle""" graph_left_x_line.set_data(t[:i], x_and_v[0,:i]) graph_left_v_line.set_data(t[:i], x_and_v[1,:i]) graph_left.relim() graph_left.autoscale_view() graph_right_x_line.set_data(t[:i], x_and_v[2, :i]) graph_right_v_line.set_data(t[:i], x_and_v[3, :i]) graph_right.relim() graph_right.autoscale_view() """Animated blocks and spring with time counter in the top middle""" block.cla() m1x = x_and_v[0][i] m2x = x_and_v[2][i] side1 = parameters['a'][0] side2 = parameters['b'][0] block.set_ylim(0, max(side1, side2)) mass1 = patches.Rectangle( (m1x - side1, 0), side1, side1, facecolor='#1f77b4') mass2 = patches.Rectangle( (m2x, 0), side2, side2, facecolor='#ff7f0e') spring = patches.ConnectionPatch(xyA=(m1x, min(side1, side2)/2), coordsA='data', xyB=(m2x, min(side1, side2)/2), coordsB='data', linewidth=2, color='k') block.add_patch(spring) block.add_patch(mass1) block.add_patch(mass2) block.annotate(f'time = {round(t[i],1)}s', xy=(0.5, 0.98), xycoords='axes fraction', ha='center', va='top') block.set_title('Block Animation') block.set_xlabel('Position [m]') block.axis('equal') fig.canvas.draw() plt.pause(0.01)# =============================================================================# Main loop that calculates each x and v value using RK 4th order method# =============================================================================i = 0while i < (steps-1): x_and_v[:, i+1] = x_and_v[:, i] + RK4(i) t[i+1] = t[i] + STEP_SIZE if i % STEPS_PER_FRAME == 0: Plotting(i) i += 1print('Done') plt.show()# plt.close() # closes the plot at then end