A SAS ODS Graphics goodbye to 2023 and hello to 2024. Happy New Year, all!
* Fun With SAS ODS Graphics: New Year's Eve Countdown w/Confetti Stars (Text+Scatter Plots);
ods graphics / height=5in width=5in noborder; /* Create animated GIF from generated images */
options nobyline papersize=('5 in', '5 in') animduration=2 animloop=yes animoverlay printerpath=gif animation=start nodate nonumber;
ods printer file='~/nye/nye.gif'; /* Animated GIF filename */
*==> Step 1: Display old year (2023) with 10-second countdown timer, reduce font size of year from 140pt to 0;
%macro oldyear;
data oldyear; /* Data to display 2023 in center of screen (0,0) */
retain x 0 y 0 year '2023';
%do secs=10 %to 0 %by -1; /* Countdown from 10 seconds to 9 */
%do subsec=0 %to 6; /* Display year 7 times per second, reducing size by 2pts each time */
proc sgplot data=oldyear aspect=1 nowall noborder pad=0 noautolegend;
styleattrs backcolor=black; /* Black background */
%let fontsize=%sysfunc(max(%eval(&secs*14-2*&subsec),0)); /* Reduce font size by 14pts each second, with 2pt intervals */
%if &secs=0 %then /* Display blank screen if # of seconds remaining =0 */
scatter x=x y=y / markerattrs=(size=0)%str(;);
%else /* Otherwise, display # of seconds remaining in middle of image */
text x=x y=y text=year / contributeoffsets=none textattrs=(color=silver weight=bold size=&fontsize.pt);;
/* Display countdown time in lower right corner of image */
inset "0:%sysfunc(putn(&secs,z2.))" / textattrs=(color=gray weight=bold size=24) position=bottomright;
xaxis display=none values=(-1 1) offsetmin=0 offsetmax=0; yaxis display=none values=(-1 1) offsetmin=0 offsetmax=0; * Suppress axes;
run;
options animduration=.14; /* Make timing somewhat close to real time (1 second per displayed #) */
%end;
%end;
%mend;
%oldyear;
*==> Step 2: Display "Happy New Year!" and the new year (2024) with "confetti" background;
data stars; /* Create 1500 points for "confetti" stars */
retain x 0 y 0;
output;
do s=1 to 1500; output; end;
data frames; /* Create 20 frames for displaying "Happy New Year!" message and year */
do frame=1 to 20; output; end;
proc sql; /* Assign random x/y points and colors, and text to be displayed */
create table stars2 as
select s.*, ranuni(0)*2-1 as xs, ranuni(1)*2-1 as ys, rand("Integer", 0, 2) as color,
case when frame<=8 then "HAPPY*NEW YEAR!" else '2024' end as msg, f.frame
from stars s, frames f order by frame;
/* Display 8 "Happy New Year!" frames with "confetti" background */
options nobyline animduration=.2;
proc sgplot data=stars2(where=(msg="HAPPY*NEW YEAR!")) aspect=1 nowall noborder pad=0 noautolegend;
by frame notsorted;
styleattrs backcolor=black;
symbolchar name=uniStar char='2605'x; /* Unicode value for 5-pointed "confetti" star */
scatter x=xs y=ys / markerattrs=(symbol=uniStar size=18Pt) colormodel=(silver gold white) colorresponse=color jitter jitterwidth=1; * Generate stars;;
text x=x y=y text=msg / splitchar='*' splitpolicy=splitalways strip contributeoffsets=none
textattrs=(color=cxf7e7ce weight=bold size=54pt); * RGB code f7e7ce is "Champagne";
xaxis display=none values=(-1 1) offsetmin=0 offsetmax=0; yaxis display=none values=(-1 1) offsetmin=0 offsetmax=0; * Suppress axes;
/* Display 12 "2024" frames with "confetti" background */
proc sgplot data=stars2(where=(msg="2024")) aspect=1 nowall noborder pad=0 noautolegend;
by frame notsorted;
styleattrs backcolor=black;
symbolchar name=uniStar char='2605'x; /* Unicode value for 5-pointed "confetti" star */
scatter x=xs y=ys / markerattrs=(symbol=uniStar size=18Pt) colormodel=(silver gold white) colorresponse=color jitter jitterwidth=1; * Generate stars;;
text x=x y=y text=msg / splitchar='*' splitpolicy=splitalways strip contributeoffsets=none
textattrs=(color=cxf7e7ce weight=bold size=140pt);
xaxis display=none values=(-1 1) offsetmin=0 offsetmax=0; yaxis display=none values=(-1 1) offsetmin=0 offsetmax=0; * Suppress axes;
run;
/* Freeze last "2024" frame for total of 2 seconds */
options nobyline animduration=1.8;
proc sgplot data=stars2(where=(frame=20)) aspect=1 nowall noborder pad=0 noautolegend;
by frame notsorted;
styleattrs backcolor=black;
symbolchar name=uniStar char='2605'x; /* Unicode value for 5-pointed "confetti" star */
scatter x=xs y=ys / markerattrs=(symbol=uniStar size=18Pt) colormodel=(silver gold white) colorresponse=color jitter jitterwidth=1; * Generate stars;;
text x=x y=y text=msg / splitchar='*' splitpolicy=splitalways strip contributeoffsets=none
textattrs=(color=cxf7e7ce weight=bold size=140.pt);
xaxis display=none values=(-1 1) offsetmin=0 offsetmax=0; yaxis display=none values=(-1 1) offsetmin=0 offsetmax=0; * Suppress axes;
run; /* Stop recording images */
options printerpath=gif animation=stop;
ods printer close;
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.
Ready to level-up your skills? Choose your own adventure.