使用 matplotlib 从数据文件制作动画

making an animation from a data file with matplotlib

我有一些生成粒子轨迹的 C++ 代码。一世。 e.不同模拟步骤中粒子的 x 和 y 坐标,其中输出文件如下所示(对于 4 个粒子):

#step0
1 2
3 4
5 6
7 8
#step1
1.2 2.2
3.2 4.3
5.2 6.4
7.2 8.5
...

我想通过从该文件中读取数据,用 matplotlib 制作动画。为此,我更改了 python 代码,但它只生成空白图像。

#!/usr/bin/python
"""
Animation of Elastic collisions with Gravity

author: Jake Vanderplas
email: vanderplas@astro.washington.edu
website: http://jakevdp.github.com
license: BSD
Please feel free to use and modify this, but keep the above information. Thanks!
"""
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

N_step = 2
N_particle = 4

class ParticleBox:
    """Orbits class

    init_state is an [N x 4] array, where N is the number of particles:
       [[x1, y1, vx1, vy1],
        [x2, y2, vx2, vy2],
        ...               ]

    bounds is the size of the box: [xmin, xmax, ymin, ymax]
    """
    def __init__(self,
                 init_state = [[1, 0, 0, -1],
                               [-0.5, 0.5, 0.5, 0.5],
                               [-0.5, -0.5, -0.5, 0.5]],
                 bounds = [-2, 2, -2, 2],
                 size = 0.04):
        self.init_state = np.asarray(init_state, dtype=float)
        self.size = size
        self.state = self.init_state.copy()
        self.time_elapsed = 0
        self.bounds = bounds

    def step(self, dt):
        """step once by dt seconds"""
        self.time_elapsed += dt
        **x,y = [], []                       
        with open("traj.xyz") as f:
            lines = f.readlines()

            Data = lines[(N_particle + 1)*self.time_elapsed:N_particle+(N_particle + 1)*self.time_elapsed] 
            for line in Data: 
                row = line.split()
                x.append(row[0])
                y.append(row[1])

        # update positions
        self.state[:, 0] = x
        self.state[:, 1] = y

#------------------------------------------------------------
# set up initial state
np.random.seed(0)
init_state = -0.5 + np.random.random((4, 4))

box = ParticleBox(init_state, size=0.04)
dt = 1.

#------------------------------------------------------------
# set up figure and animation

fig = plt.figure()
fig.subplots_adjust(left=0, right=1, bottom=0, top=1)
axes = fig.add_subplot(111, aspect='equal')
particles, = axes.plot([], [], 'bo')   

rect = plt.Rectangle(box.bounds[::2],
                     box.bounds[1] - box.bounds[0],
                     box.bounds[3] - box.bounds[2],
                     ec='none', lw=2, fc='none')
axes.add_patch(rect)

axes.grid()
axes.relim()
axes.autoscale_view(True,True,True)
#print x,y

def init():
    """initialize animation"""
    global box, rect
    particles.set_data([], [])
    rect.set_edgecolor('none')
    return particles, rect

def animate(i):
    """perform animation step"""
    global box, rect, dt, axes, fig
    box.step(dt)  
    # update pieces of the animation
    rect.set_edgecolor('k')
    particles.set_data(box.state[:, 0], box.state[:, 1])
    particles.set_markersize(10)
    return particles, rect

#plt.draw()?????
ani = animation.FuncAnimation(fig, animate, frames=3,
                              interval=10, blit=True, init_func=init)
#ani.save('particle_box.mp4', fps=30, extra_args=['-vcodec', 'libx264'])
plt.show()

您正在使用框的默认边界,这就是为什么(假设您的数据与您发布的前两个数据点相似)框中没有任何显示。

要解决此问题,请更改第 62 行 像这样:

box = ParticleBox(init_state,bounds = [-1, 10, -1, 10], size=0.04)