Creating a Moon Animation Using NASA Images and Python

2 minute read

Here’s how we can create a video of the moon in just a few lines of python code

Or you can check out the full code on my Github.

Using this NASA visualisation we can check what the moon will look like on a given day.


By opening the output image in a new tab, we see the image is located at path:

Replacing the last number in the URL (5108) with another number, 0001, we can view the first image:


We want to write some python which downloads and saves one of these images. First, we can store the URL as a string:

imageNumber = "0001"
URL = "{}.jpg".format(imageNumber)

Now we can use the urllib module to download this image to a folder we have created out.

from urllib import request
request.urlretrieve(URL, 'out/image0001.jpg')

We can now generalise this by creating a python function which takes an input imageNumber and outputdirectory:

def getImage(imageNumber, directory):
    URL = "{}.jpg".format(imageNumber)
    saveName = directory + imageNumber + ".jpg"
    request.urlretrieve(URL, saveName)

Using this function we can easily download an image, like number 0999, into folder out with getImage("0999", 'out/').

Now to download all 8761 images and create a video with high frames per second. Before the downloading, first we write a small function which assists with the ‘0001’ formatting style (moon.1.jpg does not exist!).

This requires a function which takes an integer input n, and then adds some leading 0s. The number of zeros required is equal to 4 minus the number of digits, the length of the number as a string i.e 4 - len(str(n)).

def addZeros(imageNumber):
    numAdd = 4 - len(str(imageNumber))
    return "0" * numAdd + str(imageNumber)

Now we can download image 3 using getImage(addZeros(3), 'out/').

Or, more easily, we can use Python’s string formatting:

def addZeros(imageNumber):
    return '{:04d}'.format(imageNumber)

which will add leading zeros up to 4 digits. (Thanks /u/flutefreak7)

From here we can download all 8761 images:

for imageNumber in range(1, 8761):
    print("Downloading image #{}".format(imageNumber))
    getImage(addZeros(imageNumber), 'out/')

These images might take a while to download

Once all the images have been downloaded we can create a video using the imageio module. First we create a list containing all the file locations. We can do this in a traditional loop:

files = []
for imageNumber in range(1, 8761):
    files.append('out/' + addZeros(imageNumber) + '.jpg')

or we can do this in a more pythonic way using list comprehension:

files = ['out/{}.jpg'.format(addZeros(imageNumber))
        for imageNumber in range(1, 8761)]

Now we can load all these images with imageio in a similar way:

import imageio
images = [imageio.imread(file) for file in files]

Finally, we can create a gif using:

imageio.mimsave('moonAnimation.gif', images)

Or we can create an HD video using ffmpeg:

$ ffmpeg -r 25 -i images/%04d.jpg -vb 20M moon.mp4

Check out the full code on my Github.


Leave a comment