Data visualization with SAS programming

Fun With #SAS ODS Graphics: By The Light of the Halloween Moon

Reply
Frequent Contributor
Frequent Contributor
Posts: 89

Fun With #SAS ODS Graphics: By The Light of the Halloween Moon

witch.gif

 

Another holiday, another installment of SAS ODS Graphics meets Math-Aids Four Quadrant Graphing Characters Worksheets. This one’s a GTL animated GIF remix of an SGPLOT remix of a 2015 SAS/GRAPH Halloween Witch (ever notice how SAS visualizations come in threes?). Happy Halloween, kids!

 

* Fun w/SAS ODS Graphics: Animated witch from points in math-aids.com graphing worksheet;

data Witch(keep=shapeID shapenum x y polyX polyY xmin xmax ymin ymax);
length shapeID $ 20. shapenum x y 8;
retain shapeID shapenum;                                
infile cards dsd dlm=',' truncover;  * "Cards" contain points to plot from math-aids.com;
input;
put "i=" _infile_;
if _infile_=:'Shape' then do;
  shapeID=_infile_;
  shapenum=scan(shapeID,2);
  end;
else
  do;
    i=1;
    do while(scan(_infile_, i, ' ,')^='');
      x=scan(_infile_, i, ', ');
      y=scan(_infile_, i+1, ', ');
      i+2;                                      
      polyX=x;                   * Use polygons to color witch shapes on final slide;
      polyY=y;
      xmin=-20; xmax=20;                  * "Dummy" points for consistent image size;
      ymin=-20; ymax=20;
      output;
    end;
  end;
cards;
Shape 1
-1,11 1,8 2,6 1.5,5.5 2,5 2.5,5.5 3,5 2.5,4.5 1,4.5 0,4
-1,3 -2,1 -3,-1 -3,-2 -2.5,-2.5 -1,-2 -1,-2.5 -2,-3 -4,-3.5
-4.5,-3.5 -5,-3 -6.5,-4 -13,-3 -13.5,-5 -13,-7 -12,-8.5 -10,-7
-7,-5 -6,-4.5 -4.5,-5 -4.5,-4.5 -3.5,-4 -1.5,-3.5 -1,-4.5 -1.5,-5
-2,-5 -2.5,-4.5 -3.5,-4.5 -4.5,-6 -5.5,-8 -4,-7 -2,-6 2,-5.5
4,-4.5 4.5,-4 4,-3.5 3.5,-2.5 7,-2 13,-0.5 13,0.5 11,0 9,-0.5
6,-0.5 4,0 3.5,1 3.5,3 5,3 4.5,4 5.5,3.5 6,4.5 7,5 6.5,5.5
5.5,6 5,7 5.5,7.5 5.5,8 5,7.5 4.5,7.5 4,8 2,9 -1,11
Shape 2
2.5,-0.5 4,-1.5 2.5,-2 2.5,-.5
;
                                          * Create annotation data set to draw lines;
data line(keep=function drawspace x1 y1 x2 y2 polyX polyY linecolor);
set witch;
by shapeID notsorted;
function='line';
drawspace='datavalue';
x1=lag(x);
y1=lag(y);
x2=x;
y2=y;
linecolor='black';
if ^first.shapeID;

%macro gentemplate(final=Y);                                      * Draw the witch!;
proc template;
define statgraph witchtemplate;
  begingraph
  %if &final=Y %then / backgroundcolor=black;;        * Last slide? Paint it black!;
    dynamic linenum;
    layout overlayequated / 
      walldisplay=none 
      xaxisopts=(display=none offsetmin=0.001 offsetmax=0.001 viewmin=-20 viewmax=20)
      yaxisopts=(display=none offsetmin=0.001 offsetmax=0.001 viewmin=-20 viewmax=20);
    scatterplot x=x y=y / markerattrs=(size=0);
    scatterplot x=xmin y=ymin / markerattrs=(size=0);
    scatterplot x=xmax y=ymax / markerattrs=(size=0);
    %if &final=Y %then %do;           * Add orange circle, flood-fill witch (black);
      ellipseparm semimajor=18 semiminor=18 xorigin=0 yorigin=0 slope=0 / 
                  display=all outlineattrs=(color=black) fillattrs=(color=orange);
      polygonplot x=PolyX y=PolyY id=ShapeID / 
                  colorresponse=shapenum colormodel=(black orange)
                  display=(fill) label=none outlineattrs=(color=black);
    %end;                                                             * Line counter;
    entry halign=right linenum / valign=bottom textattrs=(size=32 weight=bold color=lightgray);
    annotate;
    endlayout;
  endgraph;
end;
run;
%mend;

* Create animated GIF with one incremental plot for each line;

ods _all_ close;
options papersize=('4 in', '4 in') printerpath=gif animation=start 
        nodate nonumber animduration=1.8 animloop=YES NOANIMOVERLAY;
ods printer file='/folders/myfolders/witch.gif';
ods graphics / width=4in height=4in imagefmt=GIF;

%macro drawlines;
proc sql noprint;
select count(*) into :numlines from line;
quit;                   

%gentemplate(final=Y);                          * Display final image before drawing lines;
options animduration=1.8;
proc sgrender data=Witch template=witchtemplate sganno=line;
dynamic linenum=" "; 

options animduration=.04;                       * Line-by-line drawing;
%gentemplate(final=N); 
%do l=1 %to &numlines;                          * Draw incremental image with lines thus far;  
  proc sgrender data=Witch template=witchtemplate sganno=line(obs=&l);
  dynamic linenum="&l";
%end; 
run; 
%mend;

%drawlines;
options printerpath=gif animation=stop;
ods printer close;

 

Ask a Question
Discussion stats
  • 0 replies
  • 5166 views
  • 5 likes
  • 1 in conversation