Data visualization with SAS programming

Fun w/SAS ODS Graphics: Bringing a Math-Aids.com Jack-O-Lantern Graphing Puzzle to Life

Reply
Contributor tc
Contributor
Posts: 74

Fun w/SAS ODS Graphics: Bringing a Math-Aids.com Jack-O-Lantern Graphing Puzzle to Life

Pumpkin.gif

 

Read in the ordered pairs of points for the Jack-O-Lantern graphing puzzle from Math-Aids.com into SAS, and you can use ODS Graphics to draw, color, and "light" the pumpkin in no time at all - Happy Halloween!

 

CODE

/* File contains points for pumpkin plot from http://math-aids.com */

filename Pumpkin "/folders/myfolders/Pumpkin.txt";

data Pumpkin(keep=shapeID x y xStem yStem xLight yLight);          /* Read in pairs of points */
length shapeID $ 20. x 8 y 8;
retain shapeID;
infile Pumpkin lrecl=255;
input;
if _infile_=:'Shape' then                                          /* Each shape preceded by "Shape n" line */
  shapeID=_infile_;
else
  do;
    i=1;
    do while(scan(_infile_, i, '(), ')^='');
      x=scan(_infile_, i, '(), ');                                /* Points are surrounded by parentheses */
      y=scan(_infile_, i+1, '(), ');                              /* and separated by commas */
      if shapeid ='Shape 1' then do; xStem=x; yStem=y; end;       /* Pumpkin stem coordinates */
      if shapeid in ('Shape 10' 'Shape 11' 'Shape 12' 'Shape 7')  /* Nose, mouth, eye coordinates */
         then do; xLight=x; yLight=y; end;
      i+2;                                                        /* Points come in pairs */
      output;
    end;
  end;

data line(keep=function drawspace x1 y1 x2 y2 linecolor shapeid); /* Line segments to draw pumpkin */
set Pumpkin;
by shapeID notsorted;
function='line';
linecolor='black';
drawspace='datavalue';
x1=lag(x);
y1=lag(y);
x2=x;
y2=y;
if ^first.shapeID;

%macro genrender(colorStem=N, colorPumpkin=N, colorLight=N, color=black);
proc template;                                      /* Template for pumpkin images */                             
define statgraph ptemplate;                               
  begingraph;
    dynamic linenum;
    layout overlayequated / xaxisopts=(griddisplay=on viewmin=-12 viewmax=12 offsetmax=0) 
                            yaxisopts=(griddisplay=on viewmin=-10 viewmax=13.5 offsetmin=.05);
      scatterplot x=x y=y / markerattrs=(size=0);   /* Change size if you want to view points */
      entry halign=right linenum / valign=top textattrs=(size=36 weight=bold color=lightgray);
      annotate;
      %if &colorPumpkin=Y %then           /* Color pumpkin orange */
      polygonplot x=x y=y id=ShapeID / display=(fill) label=none fillattrs=(color=orange);;
      %if &colorStem=Y %then              /* Color stem green */
      polygonplot x=xStem y=yStem id=ShapeID / display=(fill) label=none fillattrs=(color=green);;
      %if &colorLight=Y %then             /* "Blinking" (alternate black/yellow) for nose/eyes/mouth */
      polygonplot x=xLight y=yLight id=ShapeID / display=(fill) label=none fillattrs=(color=&color);;
    endlayout;
  endgraph;
end;
run;
%mend;

* Create animated GIF with one incremental plot for each line (full pumpkin at begginning/end;

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

%macro drawlines; 
proc sql noprint;                        * Get frame count (1 per line segment;
select count(*) into :numlines from line;  
quit;                   
                                         * Display final filled/lit image before drawing lines;
%genrender(colorStem=Y, colorPumpkin=Y, colorLight=Y, color=yellow);
proc sgrender data=Pumpkin template=ptemplate sganno=line;
dynamic linenum=" ";
run;

%genrender;
options animduration=0.06;
%do l=1 %to &numlines;                   * Draw incremental image with lines thus far;  
  proc sgrender data=Pumpkin template=ptemplate sganno=line(obs=&l); dynamic linenum="&l";
  run;
%end;

options animduration=1;
%genrender;                              * Pumpkin without any fill color;
proc sgrender data=Pumpkin template=ptemplate sganno=line; dynamic linenum=" "; 
run;

%genrender(colorStem=Y);                 * Pumpkin with stem filled;
proc sgrender data=Pumpkin template=ptemplate sganno=line; dynamic linenum=" "; 
run;

%genrender(colorStem=Y, colorPumpkin=Y); * Pumpkin stem and surface filled;
proc sgrender data=Pumpkin template=ptemplate sganno=line; dynamic linenum=" "; 
run;

%do l=1 %to 10;                          * Fully-filled pumpkin with "blinking light";
  %genrender(colorStem=Y, colorPumpkin=Y, colorLight=Y, color=black);  * Light on;
  proc sgrender data=Pumpkin template=ptemplate sganno=line; dynamic linenum=" "; 
  run;
  options animduration=.25;
  %genrender(colorStem=Y, colorPumpkin=Y, colorLight=Y, color=yellow); * Light off;
  proc sgrender data=Pumpkin template=ptemplate sganno=line; dynamic linenum=" "; 
  run;
%end;
%mend;

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

DATA (JACK-O-LANTERN X-Y POINT PAIRS FROM MATH-AIDS.COM)

Shape 1
(-1,9) , (-0.5,10) , (0,11) , (1,12) , (2,13) , (3,13.5) , (3.5,12.5) , (2,11) , (1,10) , (1.5,8.5)
(2,8) , (2,7.5) , (1,7) , (0.5,7) , (0,7) , (-1,7.5) , (-1.5,8) , (-1,9)
Shape 2
(1.5,8.5) , (3,8.5) , (6,8.5) , (8,7.5) , (9.5,6.5) , (10.5,5) , (11,4) , (11.5,2) , (12,0) , (11.5,-3)
(10.5,-5) , (9,-7) , (7,-8.5) , (5,-9.5) , (3,-10) , (1,-10) , (-1.5,-10) , (-3.5,-10) , (-6,-9) , (-8.5,-7)
(-10,-5) , (-11.5,-2) , (-12,0) , (-11.5,2) , (-11,4) , (-10,6) , (-8,7.5) , (-6,8.5) , (-4,9) , (-2,9) , (-1,9)
Shape 3
(2,8) , (5,7.5) , (7,6.5) , (8.5,5) , (9.5,3) , (10,1) , (10.5,-1) , (10,-3) , (9,-5.5) , (7,-8.5)
Shape 4
(2,8) , (4,7) , (6,5) , (7,3) , (7.5,0) , (7.5,-2)
Shape 5
(7.5,-3.5) , (7,-5) , (6,-7) , (5,-9.5)
Shape 6
(0,-5.5) , (0.5,-8) , (1,-10)
Shape 7
(2,7.5) , (3,6.5) , (4,4) , (6,1) , (4.5,1) , (1.5,1) , (4,4)
Shape 8
(4.5,1) , (4.5,-1) , (4.5,-3)
Shape 9
(4,-6.5) , (4,-8) , (3,-10)
Shape 10
(0.5,7) , (0,5) , (0,0) , (-1,-1.5) , (0,-1.5) , (1.5,-1.5) , (0.5,0.5) , (0,0)
Shape 11
(0,-1.5) , (0,-3.5) , (1.5,-3.5) , (1.5,-4.5) , (3.5,-4.5) , (3,-3) , (4.5,-3) , (7.5,-2) , (8.5,-2) , (7.5,-3.5)
(6,-5) , (5,-6) , (4,-6.5) , (1.5,-7) , (1,-5.5) , (0,-5.5) , (-1,-5.5) , (-1,-7.5) , (-3,-6.5) , (-5,-5.5)
(-7.5,-1.5) , (-3.5,-3) , (-4,-4.5) , (-2,-4.5) , (-1.5,-3) , (0,-3.5)
Shape 12
(-1,7.5) , (-2.5,6) , (-3,5) , (-3.5,4) , (-1.5,1) , (-4,0.5) , (-6,0.5) , (-3.5,4)
Shape 13
(-4,0.5) , (-4,-1) , (-3.5,-3)
Shape 14
(-3,-6.5) , (-2.5,-8) , (-1.5,-10)
Shape 15
(-1.5,8) , (-2.5,8) , (-4,7) , (-5.5,6) , (-7,4) , (-8,2) , (-8,0) , (-8,-2) , (-7.5,-4) , (-7,-5.5)
(-5.5,-7.5) , (-3.5,-10)
Shape 16
(-2,9) , (-4,8.5) , (-6,7.5) , (-8,6) , (-9.5,3.5) , (-10,2) , (-10.5,0) , (-10.5,-2) , (-9.5,-4.5) , (-8.5,-7)

 

 

SAS Super FREQ
Posts: 1,080

Re: Fun w/SAS ODS Graphics: Bringing a Math-Aids.com Jack-O-Lantern Graphing Puzzle to Life

Awesome, TC!   You should get the "GTL Medal of Honor" or something!  Smiley Surprised

Valued Guide
Posts: 505

Re: Fun w/SAS ODS Graphics: Bringing a Math-Aids.com Jack-O-Lantern Graphing Puzzle to Life

Just in Time

Love it!!!

Contributor tc
Contributor
Posts: 74

Re: Fun w/SAS ODS Graphics: Bringing a Math-Aids.com Jack-O-Lantern Graphing Puzzle to Life

[ Edited ]

I probably should have mentioned that those seeking examples of serious applications of these tricks should check out a recent MWSUG Best Paper on Using Animation to Make Statistical Graphics Come to Life, as well as some older SAS Blogs posts on the subject - Animation using SGPLOT (includes a SAS take on the famous Gapminder dataviz), A 3D Scatter Plot Animation Macro, and Create an animation with the BY statement in PROC SGPLOT. Can't recall which of these I stole "borrrowed" code/techniques from - probably all 4.

Super User
Posts: 1,228

Re: Fun w/SAS ODS Graphics: Bringing a Math-Aids.com Jack-O-Lantern Graphing Puzzle to Life

Spooktacular!!! 🎃👍 Love your work! Definitely #dataviz delight! 

Ask a Question
Discussion stats
  • 4 replies
  • 1599 views
  • 9 likes
  • 4 in conversation