One option for creating animated GIFs from your visual python program is add the pillow package that allows you to export images of your vpython window from within your program. You can then use GIMP to create an animation such as the one shown here.
To use python’s image library, you can install the “pillow” package, and then use the line
from PIL import ImageGrab
to import the necessary functionality. To take an image of your vpython display, add the following
im = ImageGrab.grab((0, 0, 600, 600))
im.save('filename.jpg')
This code specifies that the image should be taken starting at the top left of your screen and extending down 600 pixels and right 600 pixels.
Once you have created a set of images, you can create the animated GIF using GIMP as follows:
- Open GIMP and go to File > Open as Layers
- Select all your images and click “Open”
- Go to Filters > Animation > Playback to see your animation
- Go to Filters > Animation > Optimize for GIF
- When you are ready, go to File > Export As
- Rename the image with the “.gif” extension.
- Select the “animation” checkbox and the frame rate
The visual python code used to create the animation of the simple pendulum above, is shown below. Notice that I set the window size for convenience, and I placed the image-grabbing code in a loop, but only took an image every five iterations.
from visual import *
import numpy as np
from PIL import ImageGrab
#
# Constants
#
g = 9.80 # (m/s^2)
L = 10 # Length of the pendulum
initialAngle = 1.3 # In radians
# Set the display window to make the image grabs easier
scene = display(title='Simple Pendulum',
x=0, y=0, width=700, height=700,
center=(0, -5, 0))
#
# Create the pendulum bob and rod
#
pend = sphere(pos=(L*np.sin(initialAngle), -L*np.cos(initialAngle), 0), radius=1, color=color.yellow)
rod = cylinder(pos=(0, 0, 0), axis=(pend.pos[0], pend.pos[1], 0), radius=0.1)
def position(time):
"""
Given time, t, this function moves the pendulum to its new position. We
use the equation:
theta(t) = theta_0*cos(sqrt(g/L)*t)
"""
theta = initialAngle*np.cos((g/L)**(1/2)*time) # Angle of the pendulum
pend.pos = [L*np.sin(theta), -L * np.cos(theta), 0] # Update position of bob
rod.axis = [pend.pos[0], pend.pos[1], 0] # Update rod's position
# Increment time
i = 0
while True:
rate(100)
position(i)
i += 0.01
if (int(i * 100)) % 5 == 0:
im = ImageGrab.grab((10, 30, 690, 690))
im.save('Images/filename' + str(int(i*100)) + '.jpg')