简体   繁体   English

python动画从文件中读取数据

[英]python animation reading data from file

I'm trying to plot the time evolution of a function f(x,t) . 我正在尝试绘制函数f(x,t)的时间演化 The data is stored in a file which has the following format: 数据存储在具有以下格式的文件中:

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)

where N is the no: of points of the simulation box and M is the number of timesteps. 其中N是模拟框中的点的编号:,M是时间步数。 I used basic_animation by Jake Vanderplas ( https://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/ ) to start with, the original example works fine as long as i put blit=False. 我使用了Jake Vanderplas的basic_animation( https://jakevdp.github.io/blog/2012/08/18/matplotlib-animation-tutorial/ )作为开始,只要我将blit = False设置为原始示例即可。

Then i tried to replace x by : 然后我试图用x替换x:

x= np.arange(0,192)

and y by the contents of the file mentioned above. y为上述文件的内容。

If i do just plt.plot(x,y) , it does plot f(x,t) at a given time t, but I want the animation of f(x,t) in time. 如果我只是做plt.plot(x,y) ,它确实在给定的时间t绘制了f(x,t) ,但是我想要及时播放f(x,t)的动画。

set_data should accept 2 1Darrays and I've checked that len(x)=len(y) . set_data应该接受2个1Darrays并且我检查了len(x)=len(y)

But I get the following error message: ' RuntimeError: xdata and ydata must be the same length' 但是我收到以下错误消息:' RuntimeError:xdata和ydata的长度必须相同'

This is the code (in the future i would like to plot multiple functions): 这是代码(将来我想绘制多个函数):

"""
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()

I'm not sure what exactly is causing your error, but let me point something out, then I'll make a toy example that should help clarify what's happening. 我不确定到底是什么引起了您的错误,但是让我指出一点,然后我将制作一个玩具示例,该示例应有助于弄清发生的情况。

These lines seem unnecessarily complicated. 这些行似乎不必要地复杂。

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))

If your data is in fact in the simple format you stated, ie, values separated by spaces, np.loadtxt() would load all the values into an easy to manage array. 如果您的数据实际上是您所说的简单格式,即用空格分隔的值,则np.loadtxt()会将所有值加载到易于管理的数组中。

Example

Lets assume this is your data file (10 time steps, 2 points on plot at each step): 让我们假设这是您的数据文件(10个时间步,每个步在图上有2点):

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

Now some code: 现在一些代码:

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

Now we load the data in with np.loadtxt() , this creates a 2-d matrix with t in the columns and x in the rows. 现在,我们使用np.loadtxt()加载数据,这将创建一个二维矩阵,其列中的t和行中的x We then transpose it to make indexing each time step possible in animate() . 然后,我们对其进行转置,以使每个时间步都可以在animate()建立索引。

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

Now for animation functions. 现在用于动画功能。 This part is really quite simple. 这部分真的很简单。 animate(i) takes one argument - the frame number. animate(i)有一个参数-帧号。 Using the frame number, we extract the values of f(x,t=frameNumber) and set that as the data on the plot. 使用帧号,我们提取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()

This is the working code: 这是工作代码:

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM