BookmarkSubscribeRSS Feed
tc
Lapis Lazuli | Level 10 tc
Lapis Lazuli | Level 10

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)

 

 

4 REPLIES 4
Jay54
Meteorite | Level 14

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

tc
Lapis Lazuli | Level 10 tc
Lapis Lazuli | Level 10

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.

MichelleHomes
Meteorite | Level 14

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

//Contact me to learn how Metacoda software can help keep your SAS platform secure - https://www.metacoda.com

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

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
  • 4 replies
  • 5021 views
  • 9 likes
  • 4 in conversation