Ask Your Question

Revision history [back]

If you want to animate a 3d plot, I think there must be a better way. Here's one hacky workaround:

First, generate a "dummy animation" with the number of frames you want, and note where the output images are stored:

N = 10
A = animate([i for i in range(N)])
print A.png()
os.system('ls '+ A.png())

This will return something like

/sagenb/sagenbws/.sage/temp/mod.math.washington.edu/13021/dir_3
00000000.png  00000002.png  00000004.png  00000006.png  00000008.png
00000001.png  00000003.png  00000005.png  00000007.png  00000009.png

Now save the list of images you want to animate, using the same names as those listed above:

def par(t):
    tmp = [[200-t,-1,0,0],[300-t,0,-1,0],[400-t,-1,-1,-1],[600-t,0,-1,-3],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
    G = Polyhedron(ieqs = tmp, field=RDF)
    return G.render_solid(rgbcolor='blue',alpha=.2)+G.render_wireframe(rgbcolor='black')+plot3d(0,(0,200),(0,300),color='red',opacity=.1)

for i in range(N):
    P = par(2+i)
    P.save(A.png()+'/%08d.png'%i)

When you call A.show(), it just checks for images in the directory returned by A.png and uses convert or ffmpeg to return a gif animation. Since you've cleverly replaced the original images generated by the animate command with the ones you want, then you will get your animation with

A.show()

Note: it's been bugging me for a long time that there's no good way to animate 3D plots. Maybe this hack will convince someone else that they should figure out a better way to do it! Alternatively, maybe this will tell me that there's already a ticket open for fixing the animate command :)


Second note: the function par from the OP seems to return the same picture, just on different scales. This makes the animation basically constant, so I threw in a fixed rectangle in the xy plane because I couldn't immediately figure out the command to set xmin, xmax or the like for 3D plots. I also updated the Polyhedron command to use floating point numbers instead of integers. This makes par accept non-integral values for some reason, and thus means that the original interact from the OP should work with this updated par function.

If you want to animate a 3d plot, I think there must be a better way. Here's one hacky workaround:

First, generate a "dummy animation" with the number of frames you want, and note where the output images are stored:

N = 10
A = animate([i for i in range(N)])
print A.png()
os.system('ls '+ A.png())

This will return something like

/sagenb/sagenbws/.sage/temp/mod.math.washington.edu/13021/dir_3
00000000.png  00000002.png  00000004.png  00000006.png  00000008.png
00000001.png  00000003.png  00000005.png  00000007.png  00000009.png

Now save the list of images you want to animate, using the same names as those listed above:

def par(t):
    tmp = [[200-t,-1,0,0],[300-t,0,-1,0],[400-t,-1,-1,-1],[600-t,0,-1,-3],[0,1,0,0],[0,0,1,0],[0,0,0,1]]
    G = Polyhedron(ieqs = tmp, field=RDF)
    return G.render_solid(rgbcolor='blue',alpha=.2)+G.render_wireframe(rgbcolor='black')+plot3d(0,(0,200),(0,300),color='red',opacity=.1)

for i in range(N):
    P = par(2+i)
    P.save(A.png()+'/%08d.png'%i)

When you call A.show(), it just checks for images in the directory returned by A.png and uses convert or ffmpeg to return a gif animation. Since you've cleverly replaced the original images generated by the animate command with the ones you want, then you will get your animation with

A.show()


Note: it's been bugging me for a long time that there's no good way to animate 3D plots. Maybe this hack will convince someone else that they should figure out a better way to do it! Alternatively, maybe this will tell me that there's already a ticket open for fixing the animate command :)


Second note: the function par from the OP seems to return the same picture, just on different scales. This makes the animation basically constant, so I threw in a fixed rectangle in the xy plane because I couldn't immediately figure out the command to set xmin, xmax or the like for 3D plots. I also updated the Polyhedron command to use floating point numbers instead of integers. This makes par accept non-integral values for some reason, and thus means that the original interact from the OP should work with this updated par function.