3

I have made a simple n-body simulator and I plot/animate the movement with the following code:

for i in range(N):
    [...]
    x = [ Rbod[j][0], Rbod[j][0]]
    y = [ Rbod[j][1], Rbod[j][1]]
    #print(R1, V1, A1, F12)
    if i%10 == 0:
        print(i)
        pylab.ion()
        pylab.scatter( x, y, c=(j/nbodies,j/nbodies,j/nbodies) )
        pylab.axis([-400, 400, -400, 400])
        pylab.draw()

Now I would really like to save the animation as a gif. Is this possible? The internet vaguely said that it was but not on how to do it with pylab.

Example of 4 body interaction: enter image description here

Mike Müller
  • 82,630
  • 20
  • 166
  • 161
Coolcrab
  • 2,655
  • 9
  • 39
  • 59
  • As far as I know, pylab has no support for animated GIFs, so you have to do one of two things: (1) Have pylab create a video, and then convert that to an animated GIF, or (2) Have pylab save snapshots, and them combine those into an animated GIF. – abarnert May 24 '13 at 22:55

3 Answers3

7

I solved it by using ffmpeg, a conversion programme ran trough the commandline. So first I save all the seperate pictures and then make them into a avi and the avi into a gif.

            print(i)
            #pylab.ion()
            pylab.scatter( x, y, c=(j/nbodies,j/nbodies,j/nbodies) )
            pylab.axis([-400, 400, -400, 400])
            #pylab.draw()
            pylab.savefig('picture'+str(i))

os.chdir('C://Users/Alex')
subprocess.call(['ffmpeg', '-i', 'picture%d0.png', 'output.avi'])
subprocess.call(['ffmpeg', '-i', 'output.avi', '-t', '5', 'out.gif'])
Coolcrab
  • 2,655
  • 9
  • 39
  • 59
2

Check out this tutorial on animation in matplotlib. http://nbviewer.ipython.org/urls/raw.github.com/jakevdp/matplotlib_pydata2013/master/notebooks/05_Animations.ipynb

A quick search shows how to create an animation as mp4, you can then convert it with a third-party tool to a format you desire.

from matplotlib import animation

# call the animator.  
...
anim = animation.FuncAnimation(fig, animate, init_func=init,
                           frames=200, interval=20, blit=True)
...
anim.save('basic_animation.mp4', fps=30)
imbr
  • 6,226
  • 4
  • 53
  • 65
yardsale8
  • 940
  • 9
  • 15
2

As simple but effective solution is to use pylab.savefig(filename) in the loop and save a file for each frame, i.e. right after pylab.draw(). The filenames should reflect the loop index, i.e. frame0001.png, frame0002.png, … Then use FFmpeg (http://www.ffmpeg.org/) to stitch them together. There is already a question and an answer how this works (Create animated gif from a set of jpeg images). FFmpeg has a lot of options. For example, you can adjust the frame rate.

Community
  • 1
  • 1
Mike Müller
  • 82,630
  • 20
  • 166
  • 161
  • I'm not very good with 3rd party things as I'm on win7. Could you maybe tell me how to use this? As it doesn't look like a plugin for python. – Coolcrab May 25 '13 at 07:42
  • FFmpeg is a standalone program: 1. Download it: http://ffmpeg.zeranoe.com/builds/ 2. Install it. 3. Run it from the command line as explained in http://stackoverflow.com/questions/3688870/create-animated-gif-from-a-set-of-jpeg-images – Mike Müller May 25 '13 at 14:17