Create an animation with the BY statement in PROC SGPLOT

Create an animation by using the BY statement in the PROC SGPLOT

It is easy to use PROC SGPLOT and BY-group processing to create an animated graph in SAS 9.4. Sanjay Matange previously discussed how to create an animated plot in SAS 9.4, but he used a macro loop to call PROC SGPLOT many times.

It is often easier to use the BY statement in SAS procedures to create many graphs. Someone recently asked me how I created an animation that shows level sets of a contour plot. This article explains how to create an animation by using the BY statement in PROC SGPLOT.

An animation requires that you create a sequence of images. In SAS 9.4, you can create an animated GIF by using the ODS PRINTER destination. ODS does not care how the images are generated. They can be created by a macro loop. Or, as shown below, they can be generated by using the BY statement in PROC SGPLOT, SGRENDER, or any other procedure in SAS.

As an example, I will create the graph at the top of this article, which shows the annual time series for the stock price of three US companies for 20 consecutive years. The data are contained in the Sashelp.Stocks data set. The following DATA step adds two new variables: Year and Month. The data are then sorted according to Date, which also sorts the data by Year.

data stocks;
   set sashelp.stocks;
   Month = month(date);      /* 1, 2, 3, ..., 12 */
   Year = year(date);        /* 1986, 1987, ..., 2005 */
proc sort data=stocks; by date; run;

I will create an animation that contains 20 frames. Each frame will be a graph that shows the stock performance for the three companies in a particular year. You can use PROC MEANS to discover that the stock prices are within the range [10, 210], so that range is used for the vertical axis:

ods graphics / imagefmt=GIF width=4in height=3in;     /* each image is 4in x 3in GIF */
options papersize=('4 in', '3 in')                    /* set size for images */
        nodate nonumber                               /* do not show date, time, or frame number */
        animduration=0.5 animloop=yes noanimoverlay   /* animation details */
        printerpath=gif animation=start;              /* start recording images to GIF */
ods printer file='C:\AnimGif\ByGroup\Anim.gif';  /* images saved into animated GIF */
ods html select none;                                 /* suppress screen output */
proc sgplot data=stocks;
title "Stock Performance";
   by year;                                           /* create 20 images, one for each year */
   series x=month y=close / group=stock;              /* each image is a time series */
   xaxis integer values=(1 to 12);                         
   yaxis min=10 max=210 grid;                         /* set common vertical scale for all graphs */
ods html select all;                                  /* restore screen output */
options printerpath=gif animation=stop;               /* stop recording images */
ods printer close;                                    /* close the animated GIF file */

The BY statement writes a series of images. They are placed into the animated GIF file that you specify on the FILE= option in the ODS PRINTER statement.

A few tricks are worth mentioning:
  • Use the ODS GRAPHICS statement to specify the size of the image in some physical measurement (inches or centimeters). On the OPTIONS statement, specify those same measurements.
  • You can control the animation by using SAS system options. To create an animated GIF, use OPTIONS PRINTERPATH=GIF ANIMATION=START before you generate the image files. Use OPTIONS PRINTERPATH=GIF ANIMATION=STOP after you generate the image files.
  • Use the ANIMDURATION= option to specify the time interval (in seconds) that each frame appears. Typical values are 0.1 to 0.5.
  • Use the ANIMLOOP= option to specify whether the animation should repeat after reaching the end
  • Use ODS HTML SELECT NONE to prevent the animation frames from appearing in your HTML output. (If you use the LISTING output, replace "HTML" with "LISTING.")
  • By default, the levels of the BY group are automatically displayed in the TITLE2 field of the graph. You can turn off this behavior by specifying the NOBYLINE option. You can use the expression #BYVAL(year) in a TITLE or FOOTNOTE statement to incorporate the BY-group level into a title or footnote.

You can use a browser to view the image. As I did in this blog post, you can embed the image in a web page.

Have fun creating your animations! Leave a comment and tell me about your animated creations.


About Author

Rick Wicklin

Distinguished Researcher in Computational Statistics

Rick Wicklin, PhD, is a distinguished researcher in computational statistics at SAS and is a principal developer of SAS/IML software. His areas of expertise include computational statistics, simulation, statistical graphics, and modern methods in statistical data analysis. Rick is author of the books Statistical Programming with SAS/IML Software and Simulating Data with SAS.


  1. Pingback: Animate snowfall in SAS - The DO Loop

  2. Is there a way to include a stop, start or move forward controls for these animations? I have a request from a colleague to create an animated graphic, but they want to control it as well.

    • Rick Wicklin

      The only thing the SAS code does is to produce a bunch of GIF files. You use other software to assemble and play the animation. I assume that you can find some software that will enable you to start/stop as you view the sequence of images.

  3. Why would I be getting the following errors when trying to recreate this?
    ERROR 13-12: Unrecognized SAS option name AMIMDURATION.
    ERROR 13-12: Unrecognized SAS option name ANIMLOP.
    ERROR: The HTML destination is not active; no select/exclude lists are available.

    • Rick Wicklin

      One possibility is that you are running an old version of SAS. The animation options were introduced in SAS 9.4.

      The warning about the HTML destination is explained in the last set of bullet points: "If you use the LISTING output, replace HTML with LISTING."

  4. Just a quick note to say thank you for your INVALUABLE assistance. You have helped me so much over the years!! thank you!!! A
    A. Sauaia, MD, PhD
    Professor of Public Health
    University of Colorado Anschutz Medical Campus

Leave A Reply

Back to Top