Visualisation - Creating a Moving Stata Graphic

Visualisation is an important part of the communication of results and ideas from all areas of study. It is an especially useful tool when communicating with the general public, as it allows complex ideas to be communicated and understood more easily than mere words can manage. One of the visual tools commonly used are videos, which can come in many forms including short videos with accompanying sound, or GIF images which are very short repeatable videos.

For this tech tip I am going to look at creating a moving Stata graphic from a set of images. To do this, I first set up a loop in Stata to generate a progression of still images. To create my gif I have two options. The first is to utilize Stata’s ability to call python or java and create the GIF image from still images using programming. This allows me to generate the GIF entirely within Stata.

Alternatively, I can upload the images generated from Stata to this website: ezgif. This is just one of many free and paid websites and computer programs capable of generating GIFs from still images. If you are not familiar with programming in python or java via Stata it may be easier to use an online tool such as this.

How to Use:

Generating Images:

Make sure your current working directory is the one you want to save all your image files to.

forvalues i = xx(z)yy {
insert graph command here (e.g. twoway scatter x y)
graph export name`i'.png, as(png) replace
}

Generating a GIF from the Images:

You can use python within Stata to create the GIF. You will need to have python installed and working on your computer and you will need to download/pre-install the imageio and pygifsicle python packages. You can install the python packages via your command line/terminal with the following code:

pip install imageio
pip install pygifsicle

The following is an example of some python code in a do-file that can create a moving graphic:

python:
import imageio
from pygifsicle import optimize
gif_path = "PATH/gifname.gif"
frames_path = "PATH/gifname{i}.png"
with imageio.get_writer(gif_path, mode='I', fps=5) as writer:
	for i in range(xx,yy,z):
		writer.append_data(imageio.imread(frames_path.format(i=i)))
optimize(gif_path)
end

*NOTE*: In both the Stata code and the python code above, ‘z’ refers to the step value. For example, xx(z)yy in Stata might be 0(2)10 which would result in the range 0, 2, 4, 6, 8, 10. And (xx,yy,z) in python could be (0,10,2) which would result in the same range above. The ‘z’ is optional and does not need to be specified if you are stepping in values of positive 1. If your range increase is positive 1, then for Stata xx(z)yy becomes xx/yy, and for python (xx,yy,z) becomes (xx,yy).

In the example I use below I will demonstrate the GIF generation using python code in Stata. However, feel free to make use of a free online tool instead once you have generated the images. Making sure you use the range of numbers as part of the still-image naming process will make it really easy for the online tools to order your images when creating a gif online.

Worked Example:

In this example I am going to use the Stata example dataset uslifeexp.dta, which contains data sourced from the CDC website. I am going to plot the life expectancy of white and black people from the year 1900 to 1999. For your information, in the below code “le” stands for “life expectancy”. The dataset uses it to name some variables, and I use it to prefix the name of each image I save. In the command pane, I type the following:

cd "C:\Users\my name\Documents\life expectancy CDC"
sysuse uslifeexp
set graphics off
forvalues i = 1900(1)1999 {
twoway line le year if year <= `i', xlabel(1900(10)1999) xtitle("Year") ylabel(30(5)80) ytitle("Life Expectancy (Years)") title("Life Expectancy in the USA") note("Source: https://www.cdc.gov/nchs/data/nvsr/nvsr50/nvsr50\_06.pdf")
graph export le`i'.png
}
set graphics on

This loop command generates 100 images, each showing life expectancy from year 0 (1900) to year x (the first still shows only 1900, the next 1900 and 1901, the next 1900 to 1902, etc.).

To create my GIF using python in Stata, I use the following commands in a do-file:

python:
import imageio.v2 as imageio
from pygifsicle import optimize
gif_path = "C:\Users\my name\Documents\life expectancy CDC\lifeexp.gif"
frames_path = "C:\Users\my name\Documents\life expectancy CDC\le{i}.png"
with imageio.get_writer(gif_path, mode='I', fps=60) as writer:
	for i in range(1900,1999):
		writer.append_data(imageio.imread(frames_path.format(i=i)))
optimize(gif_path)
end

Alternatively, to create my GIF using the online tool, I load the website ezgif and upload all my photos using the shift-click select method. I then click the “Upload and make a GIF!” button and wait for my 100 still images to finish uploading. Once fully uploaded, I scroll past all the images to the options at the bottom and change my frame speed from 20ms to 50ms. I then click the “Make a GIF!” button.

With either option, the following GIF is generated:

To save the GIF using the online tool, I simply right-click the image and click “Save image as…” making sure to save it as a GIF file.