python动画从文件中读取数据

时间:2017-02-12 18:04:04

标签: python

我试图绘制函数f(x,t)的时间演变。数据存储在具有以下格式的文件中:

1st row:f(0,0) f(0,1) f(0,2) ....f(0,N)

2nd row:f(1,0) f(1,1) f(1,2) ....f(1,N)

Mth row:f(M,0) f(M,1) f(M,2) ....f(M,N)

其中N是模拟框的点数:M是时间步数。 我使用了Jake Vanderplas(https://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/)的basic_animation开始,只要我把blit = False,原始的例子就可以正常工作。

然后我试图将x替换为:

x= np.arange(0,192)

和y由上述文件的内容组成。

如果我只是plt.plot(x,y),它会在给定时间t绘制f(x,t),但我希望及时获得f(x,t)的动画。

set_data应该接受2 1Darrays并且我已经检查了len(x)=len(y)

但是我收到以下错误消息: ' RuntimeError:xdata和ydata的长度必须相同'

这是代码(将来我想绘制多个函数):

"""
Modified Matplotlib Animation Example
original example:
email: vanderplas@astro.washington.edu
website: http://jakevdp.github.com
license: BSD
Feel free to use and modify this, but keep the above information.   
"""

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
from itertools import islice


filename = 'DensityByPropagation__a_0_VHxcS_kick'

# First set up the figure, the axis, and the plot element we want to    animate
fig = plt.figure()
ax = plt.axes(xlim=(0, 192), ylim=(-2, 2))
lineS, = ax.plot([], [], lw=2)

# initialization function: plot the background of each frame
def init():
       lineS.set_data([], [])
       return lineS,

# animation function.  This is called sequentially
def animate(i):
   w = np.linspace(0, 2, 1000)
   z = np.sin(2 * np.pi * (w - 0.01 * i))

   x= np.arange(0,192)
   with open(filename) as fobj:
       ketchup = islice(fobj, 0, None, 10)
       for line in ketchup:
            x,y = x,zip(*([float(y) for y in line.split("\t")] for line in fobj))

            #plt.plot(x,y)
            #plt.show()
#print len(x)
#print len(y)
            #lineS.set_data(w,z)
            lineS.set_data(x,y)
    return lineS,

# call the animator.  blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
                           frames=200, interval=20, blit=False)

# save the animation as an mp4.  This requires ffmpeg or mencoder to be
# installed.  The extra_args ensure that the x264 codec is used, so that
# the video can be embedded in html5.  You may need to adjust this for
# your system: for more information, see
# http://matplotlib.sourceforge.net/api/animation_api.html

anim.save('movieJoh.mp4', fps=30, extra_args=['-vcodec', 'libx264'])

plt.show()

2 个答案:

答案 0 :(得分:0)

我不确定究竟是什么导致了您的错误,但让我指出一些问题,然后我会制作一个玩具示例,以帮助澄清正在发生的事情。

这些线条似乎不必要地复杂。

with open(filename) as fobj:
    ketchup = islice(fobj, 0, None, 10)
    for line in ketchup:
        x,y = x,zip(*([float(y) for y in line.split("\t")] for line in fobj))

如果您的数据实际上是您所说的简单格式,即以空格分隔的值,np.loadtxt()会将所有值加载到易于管理的数组中。

实施例

让我们假设这是你的数据文件(10个步骤,每个步骤2点):

0 0 0 0 0 0 0 0 0 0
9 8 7 6 5 4 3 2 1 0

现在有些代码:

filename = 'data.txt'

# First set up the figure, the axis, and the plot element we want to animate
fig = plt.figure()
ax = plt.axes(xlim=(0, 1), ylim=(0, 9))
lineS, = ax.plot([], [], lw=2)

x = range(2) # the domain

现在我们使用np.loadtxt()加载数据,这会在列中创建一个带有t的二维矩阵,并在行中创建x。然后,我们将其转置为在animate()中每次执行索引编制索引。

# load the data from file
data = np.loadtxt(filename)
# transpose so we could easily index in the animate() function
data = np.transpose(data)

现在用于动画功能。这部分非常简单。 animate(i)接受一个参数 - 帧编号。使用帧编号,我们提取f(x,t=frameNumber)的值并将其设置为绘图上的数据。

# initialization function: plot the background of each frame
def init():
    lineS.set_data([], [])
    return lineS,

# animation function.  This is called sequentially
def animate(i):
    lineS.set_data(x, data[i])
    return lineS,

# call the animator.  blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
                           frames=10, interval=100, blit=True)

plt.show()

答案 1 :(得分:0)

这是工作代码:

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

# Input
filename = 'PeriodicDensity'    # Filename

x = np.linspace(-7.5,7.5,192)   # Domain
xLimits=[-7.5,7.5]          # x limits
yLimits=[0,1]           # y limits
framesToUse = range(1,9000,150)# The time-steps to plot

# load the data from file
data = np.loadtxt(filename)

# Set up the figure, the axis, and the plot element we want to animate
fig = plt.figure()
ax = plt.axes(xlim=xLimits,ylim=yLimits)
lineS, = ax.plot([], [], lw=2)

# Initialisation function
def init():
   lineS.set_data([],[])
   return lineS,

# Animation function (called sequentially)
def animate(i):
    lineS.set_data(x,data[i])
    return lineS,

# call the animator.  blit=True means only re-draw the parts that have      changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,interval=1000, frames=framesToUse, blit=True)

# save the animation as an mp4.  This requires ffmpeg or mencoder to be
# installed.  The extra_args ensure that the x264 codec is used, so that
# the video can be embedded in html5.  You may need to adjust this for
# your system: for more information, see
# http://matplotlib.sourceforge.net/api/animation_api.html

anim.save('movieDensity.mp4', fps=1, extra_args=['-vcodec', 'libx264'])

plt.show()