BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
lindseyn
Obsidian | Level 7

Hi all,

 

I am new to SAS and am exploring the GIF animations that you can use on a map to show the spreading of something. I was using the code below from "Rob the Graph Guy" here on SAS and was getting the following errors/warnings:

 

ERROR: 'PRINTERPATH' is not a valid unit or graphics option. It will
be ignored.
ERROR: 'ANIMDURATION' is not a valid unit or graphics option. It will
be ignored.
ERROR: 'ANIMATE' is not a valid unit or graphics option. It will
be ignored.
ERROR: 'ANIMLOOP' is not a valid unit or graphics option. It will
be ignored.
ERROR: 'ANIMOVERLAY' is not a valid unit or graphics option. It will
be ignored.

 

WARNING: Invalid device 'SASPRCT' for RTF(WEB) destination.
Using default device 'EMF'.
WARNING: Invalid device 'SASPRCT' for PDF(WEB) destination.
Using default device 'SASPRTC'.
WARNING: Invalid device 'SASPRCT' for HTML destination.
Using default device 'PNG'.
 

ods _all_ close;
ods listing;

%let name=walmart_openings;
filename odsout '.';

%let litegray=graybb;

/*
Imitation & enhancement of:
http://www.excelhero.com/blog/2010/04/excel-location-mapping.html
Using data from:
http://www.econ.umn.edu/~holmes/data/WalMart/index.html
http://www.econ.umn.edu/~holmes/data/WalMart/store_openings.csv

Note: This example uses new SAS 9.4 syntax for the gif animation.
*/

PROC IMPORT OUT=my_data DATAFILE="C:/Users/lindsey.nelson/Documents/walmart_openings.csv" DBMS=CSV REPLACE;
GETNAMES=YES;
DATAROW=2;
RUN;

/*
Get the variable names & types the way Proc Geocode wants them
*/
data my_data; set my_data
(rename=(
streetaddr=address
strcity=city
strstate=state
));
zip=.; zip=zipcode;
run;

/*
Determine the approx lat/long of each store.
Proc Geocode could also do street-level geocoding, but when plotting data
at the US level street-level geocoding is overkill.
*/
proc geocode data=my_data out=my_data
lookup=sashelp.zipcode method=CITY;
run;

data city_matches; set my_data (where=(_matched_^='None'));
run;

/*
If you couldn't get a city name match (probably because of differences
in the way city names are spelled in the csv data, and the lookup data,
do a zipcode lookup instead.
*/
proc geocode data=my_data (where=(_matched_='None')) out=zip_matches
lookup=sashelp.zipcode method=ZIP;
run;

data my_data; set city_matches zip_matches;
run;

proc sort data=my_data out=my_data;
by opendate;
run;


/* convert degrees to westlong radians, to be like the map */
data anno_dots (drop=state); set my_data;
anno_flag=1;
long=x;
lat=y;
statecode=state;
year=year(opendate);
run;


/* Get the state abbreviations, and their lat/long locations */
data anno_states; set mapsgfk.uscenter (where=(statecode not in ('AK' 'HI' 'DC')));
anno_flag=2;
run;


/* Get the map */
data state_map;
set mapsgfk.us_states (where=(fipstate(state) not in ('AK' 'HI') and (density<3)));
run;


/* combine, project, and separate */
data combined; set state_map anno_dots anno_states; run;
proc gproject data=combined out=combined latlong eastlong degrees dupok;
id statecode;
run;
data state_map anno_dots anno_states; set combined;
if anno_flag=1 then output anno_dots;
else if anno_flag=2 then output anno_states;
else output state_map;
run;

/* annotate red dot markers */
data anno_dots; set anno_dots;
length function $8 color $20 text $20;
xsys='2'; ysys='2'; hsys='3'; when='a';
function='pie'; rotate=360; size=0.7;
style='psolid'; color='Aff000077'; output; /* v9.3 alpha-transparent red */
style='pempty'; color='gray66'; line=1; output;
run;

/* Create an annotate dataset with the state abbreviations, to use to label
each of the states. The tricky part is that you want some labels to be
out over the ocean. */
/* this code modified from online help example */
data anno_states;
length function $8 color $20 style $20;
xsys='2'; ysys='2'; hsys='3'; when='a';
retain flag 0;
set anno_states;
function='label';
style='albany amt/bold';
text=fipstate(state);
size=2.25;
color='gray66';
position='5';
if ocean='Y' then
do;
position='6';
output;
function='move';
flag=1;
end;
else if flag=1 then
do;
function='draw';
size=.25;
flag=0;
end;
output;
run;

/* ------------------------------------------------------------------ */

%macro do_year(year);

data temp_dots; set anno_dots (where=(year<=&year));
run;

proc sql noprint;
select count(*) format=comma10.0 into :year_cnt separated by ' ' from temp_dots where style='psolid' and year=&year;
select count(*) format=comma10.0 into :totalcnt separated by ' ' from temp_dots where style='psolid';
quit; run;

data data_anno;
length text $100;
xsys='3'; ysys='3'; hsys='3'; when='a';
function='label'; style='albany amt/bold'; color='gray44';
x=5; position='6';
text="Total Stores: &totalcnt"; y=22.5; size=3; output;
text="Store Openings: &year_cnt"; y=18.5; size=3; output;
text="&year"; y=12; size=15; output;
x=77; position='5';
text="Growth of"; y=95; size=7; output;
text="Walmart"; y=87; size=9; output;
run;

data all_anno;
set anno_states temp_dots data_anno;
run;

goptions gunit=pct ftitle="albany amt/bold" ftext="albany amt" htitle=5 htext=3.0;

pattern1 v=s c=cxf7e7bd;

proc gmap map=state_map data=state_map all;
id statecode;
choro state / levels=1 nolegend
coutline=gray66 anno=all_anno
des='' name="&name";
run;

%mend;

/* ------------------------------------------------------------------ */

 

goptions xpixels=1000 ypixels=650;
goptions border;


goptions dev=sasprct printerpath=gif
animduration=.5 animloop=0
animoverlay=no animate=start;

ods listing close;
ods html path=odsout body="&name..htm"
(title="Walmart Openings in the US, over time")
style=htmlblue;

%do_year(1968);
%do_year(1969);
%do_year(1970);
%do_year(1971);
%do_year(1972);
%do_year(1973);
%do_year(1974);
%do_year(1975);
%do_year(1976);
%do_year(1977);
%do_year(1978);
%do_year(1979);
%do_year(1980);
%do_year(1981);
%do_year(1982);
%do_year(1983);
%do_year(1984);
%do_year(1985);
%do_year(1986);
%do_year(1987);
%do_year(1988);
%do_year(1989);
%do_year(1990);
%do_year(1991);
%do_year(1992);
%do_year(1993);
%do_year(1994);
%do_year(1995);
%do_year(1996);
%do_year(1997);
%do_year(1998);
%do_year(1999);
%do_year(2000);
%do_year(2001);
%do_year(2002);
%do_year(2003);
%do_year(2004);
%do_year(2005);
%do_year(2006);
%do_year(2006);
%do_year(2006);
%do_year(2006);
%do_year(2006);
%do_year(2006);
%do_year(2006);
%do_year(2006);
%do_year(2006);
%do_year(2006);
%do_year(2006);
%do_year(2006);
%do_year(2006);

quit;
ods html close;
ods listing;

 

Does anyone know where these errors would be occurring for me?

Thanks!

1 ACCEPTED SOLUTION

Accepted Solutions
Rick_SAS
SAS Super FREQ
12 REPLIES 12
Reeza
Super User
Yeah, you're likely not using SAS Base, you're likely using SAS Studio or EG which has different options.

This is also a really old method, you should likely be using SGMAP these days instead which is cleaner. To make animated graphs, first start off with getting your base graphs created properly. Once you have that done it's quite easy to convert to an animated graphics. Do you have code that generates the map you want?

I think there's an example of animated maps on the SAS graphics blog.
lindseyn
Obsidian | Level 7

If this is the code for my map:

 

ods graphics / reset width=6.4in height=4.8in;

proc sgmap 
	plotdata=flu_DATA;
	openstreetmap;
	title 'Influenza Outbreaks Over Time';
	scatter x=LONGITUDE y=LATITUDE/ markerattrs=(size=6 symbol=circlefilled);
run;

ods graphics / reset;
title;

and the graph produced looks like this:

2019-07-11 10_27_10-SAS Studio - Single User.png

How would animate this by having the points appear by the date they occurred? The code I used earlier for animation gives me an error.

Thanks for your help!

Reeza
Super User
Use this code example then, from my github repository. It's a line chart over time. Assuming your dates are SAS dates you should be able to replace my sgplot with yours and then specify the dates accordingly. You also need to modify your WHERE condition to use your variables as the filter.

https://github.com/statgeek/SAS-Tutorials/blob/master/sgplot_line_graph_animation
lindseyn
Obsidian | Level 7

When I used the exact same code/example from your GitHub it produces separate graphs for each date not animation. Why would this be?

Reeza
Super User
You should actually get both...what happens to create those graphics is similar to how a flip book is generated, those where you flip the page and it looks like the image is moving? That's essentially what's happening here, you just have a lot of pages and it's created automatically. So you should get both an image for every time period as well as a gif file that is the combined animated version of them.
lindseyn
Obsidian | Level 7

In your example, what does the line of code "ods printer file='/folders/myfolders/LineGraph.gif';" do? and when and where did you create it?

 

 

Reeza
Super User
It creates/combines the animations into a single document. It's created as part of the output of the program.
Rick_SAS
SAS Super FREQ

For an overview of animation in PROC SGPLOT, see 

"Create an animation with the BY statement in PROC SGPLOT"

 

lindseyn
Obsidian | Level 7

When using this example, the individual images appear but not the gif animation. I am getting the warning 

 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
Reeza
Super User
I don't believe any code references RTF, so if you do have word as one of your default destinations you can close it ahead of time.

ODS RTF CLOSE;

The GIF should still be created, just not in the Word doc, it will be in a file on it's own. Can you post your full code and log if it still isn't working. You've marked it solved so not sure if it is or isn't working anymore.
lindseyn
Obsidian | Level 7
ODS RTF CLOSE;
ods listing close;

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

ods graphics / imagefmt=GIF outputfmt=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:\Users\lindsey\Documents\Gifs';  /* 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 */
run;
ods html select all;                          /* restore screen output */
 
options printerpath=gif animation=stop;               /* stop recording images */
ods printer close;                                  /* close the animated GIF file */

Log:

 
 1          OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 NOTE: ODS statements in the SAS Studio environment may disable 
 some output features.
 73         
 74         ODS RTF CLOSE;
 75         ods listing close;
 76         
 77         ods html;
 NOTE: Writing HTML Body file: sashtml19.htm
 78         data stocks;
 79            set sashelp.stocks;
 80            Month = month(date);      /* 1, 2, 3, ..., 12 */
 81            Year = year(date);        /* 1986, 1987, ..., 2005
 81       !  */
 82         run;
 
 NOTE: There were 699 observations read from the data set 
       SASHELP.STOCKS.
 NOTE: The data set WORK.STOCKS has 699 observations and 10 
       variables.
 NOTE: DATA statement used (Total process time):
       real time           0.01 seconds
       cpu time            0.00 seconds
       
 
 83         
 84         proc sort data=stocks; by date; run;
 
 NOTE: There were 699 observations read from the data set 
       WORK.STOCKS.
 NOTE: The data set WORK.STOCKS has 699 observations and 10 
       variables.
 NOTE: PROCEDURE SORT used (Total process time):
       real time           0.02 seconds
       cpu time            0.01 seconds
       
 
 85         
 86         ods graphics / imagefmt=GIF outputfmt=gif width=4in
 86       ! height=3in;     /* each image is 4in x 3in GIF */
 87         options papersize=('4 in', '3 in')
 87       !  /* set size for images */
 88                 nodate nonumber
 88       !  /* do not show date, time, or frame number */
 89                 animduration=0.5 animloop=yes noanimoverlay
 89       !  /* animation details */
 90                 printerpath=gif animation=start;
 90       !  /* start recording images to GIF */
 91         ods printer
 91       ! file='C:\Users\lindsey\Documents\Gifs';  /*
 91       ! images saved into animated GIF */
 NOTE: Writing ODS PRINTER output to DISK destination 
       "C:\Users\lindsey.nelson\Documents\Gifs", printer "gif".
 92         
 93         ods html select none;
 93       ! /* suppress screen output */
 94         proc sgplot data=stocks;
 95         title "Stock Performance";
 96            by year;
 96       !  /* create 20 images, one for each year */
 97            series x=month y=close / group=stock;
 97       !  /* each image is a time series */
 98            xaxis integer values=(1 to 12);
 99            yaxis min=10 max=210 grid;
 99       !  /* set common vertical scale for all graphs */
 100        run;
 
 NOTE: PROCEDURE SGPLOT used (Total process time):
       real time           7.05 seconds
       cpu time            3.12 seconds
       
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 WARNING: RTF destination does not support GIF images. Using the 
          default static format.
 NOTE: There were 699 observations read from the data set 
       WORK.STOCKS.
 
 101        ods html select all;                          /*
 101      ! restore screen output */
 102        
 103        options printerpath=gif animation=stop;
 103      !  /* stop recording images */
 104        ods printer close;
 104      ! /* close the animated GIF file */
 ERROR: Invalid file, C:\Users\lindsey\Documents\Gifs.
 105        
 106        OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 118        

And I am sorry, I thought it was working but then the file would did not appear in my created folder.

Reeza
Super User

The ERROR is what you need to fix and I posted the answer in the other thread. You didn't provide a file name for the GIF, just a path.

ERROR: Invalid file, C:\Users\lindsey\Documents\Gifs.

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 12 replies
  • 2367 views
  • 1 like
  • 3 in conversation