Here's a Newton's Cradle-inspired animated GIF ball drop to roll out the old year - Happy New Year, all!
* Fun With SAS ODS Graphics: New Year's Eve Newton's Cradle Ball Drop
Info on Newton's Cradle at en.wikipedia.org/wiki/Newton%27s_cradle;
data balls; * Generate x/y points for 4 balls in Newton's Cradle;
r=7.45; y0=8; pi=constant("pi"); * End balls swing through 30 degree arcs, middle balls stay contant;
do outerframe=0 to 11; * 12 time periods - beginning, 10-to-0 seconds countdown, end ending;
if outerframe=11 then do; mtext='HAPPY NEW YEAR!'; mX=0; mY=8.3; end; * 11th frame displays Happy New Year!;
ball=1; text='2'; x0=-1.5; * Ball one ('2') swings through 30 degree arc;
frame=0;
do a=90 to 120 by 6, 120 to 96 by -6;
radians=2*pi*a/360;
x=x0+r*cos(radians);
y=y0-r*sin(radians);
angle=-(a-90); * Ball only swings on alternate time periods;
if outerframe in (0, 11) or mod(outerframe,2)=0 then do; angle=0; x=x0; y=y0-r; end;
frame+1;
output;
end; * Balls two ('0') and three ('2') are fixed and do not swing;
ball=2; text='0'; x=-.5; x0=-.5; y=y0-r; angle=0; do frame=1 to 11; output; end;
ball=3; text='2'; x=.5; x0=.5; y=y0-r; angle=0; do frame=1 to 11; output; end;
ball=4; text='4'; x0=1.5;
frame=0;
do a=-270 to -300 by -6, -300 to -276 by 6; * Ball four ('4' or '5') swings through 30 degree arc;
radians=2*pi*a/360;
x=x0+r*cos(radians);
y=y0-r*sin(radians);
angle=-(a+270); * Ball only swings on alternate time periods;
if outerframe in (0, 11) or ^mod(outerframe,2)=0 then do; angle=0; x=x0; y=y0-r; end;
frame+1;
output;
end;
end;
proc sql; * No arcs for first/last loops, flip year from 2024 --> 2025 on last swing return;
delete from balls where outerframe in (0,11) and frame>1;
update balls set text='5' where ball=4 and (outerframe=11 or (outerframe>=10 and frame>=8));
proc sort data=balls; by outerframe frame; * Order to allow BY statement to be used in plots;
ods graphics / reset height=8in width=8in noborder; * Create animated GIF from generated images;
options nobyline papersize=('8 in', '8 in') animduration=2 animloop=yes printerpath=gif animation=start nodate nonumber;
ods printer file='~/nye/nye2025.gif'; * Animated GIF filename;
%macro genplots; /* Use macros to produce 12 sets of frames */
%macro genplot(n); /* Each set of frames takes about 1 second (countdown) with pauses before and after */
%if &n=0 %then options animduration=1.5 %str(; run;); /* Opening frame */
%else %if &n=11 %then options animduration=2 %str(; run;); /* Countdown frames */
%else options animduration=.1 %str(; run;); /* Final frame (2025) */
/* Plot the Newton's Cradle (Vector+Ellipse+Text plots) */
proc sgplot data=balls(where=(outerframe=&n)) nowall noautolegend nowall noborder noautolegend;
by outerframe frame; /* Use BY statement to create multiple plots for animation */
styleattrs backcolor=black; /* Black background */
vector x=x y=y / noarrowheads xorigin=x0 yorigin=y0 lineattrs=(color=cxa9acb6 thickness=2.5pt); /* Strings */
ellipseparm semimajor=.5 semiminor=.5 / xorigin=x yorigin=y nooutline lineattrs=(color=cxa9acb6) fill fillattrs=(color=cxa9acb6); /* Balls */
text x=x y=y text=text / rotate=angle strip textattrs=(color=black size=36pt weight=bold) contributeoffsets=none; /* Year digits */
refline 8.3 / axis=y lineattrs=(thickness=28pt color=cxa9acb6); /* Newton's cradle bar */
text x=mX y=mY text=mText / strip textattrs=(color=black size=20pt weight=bold) contributeoffsets=none; /* Happy New Year! message */
xaxis display=none values=(-5 5) offsetmin=0 offsetmax=0; /* Suppress axis info, limit bounds */
yaxis display=none values=(-1 9) offsetmin=0 offsetmax=0; /* Suppress axis info, limit bounds */
inset %if &n=0 %then "0:10"; %else %if &n=11 %then "0:00"; %else "0:%sysfunc(putn(%eval(10-&n+1),z2.))"; / position=bottom noborder textattrs=(color=cxa9acb6 size=24pt); /* Countdown timer */
run;
%mend;
%do n=0 %to 11; %genplot(&n); %end; /* 12 sets of frames */
%mend;
%genplots;
options printerpath=gif animation=stop; * Stop recording images;
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.