使用 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)
我有一些生成粒子轨迹的 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)