Inspired by Amanda Newton's clever The Heart of Mathematics (Valentine's Day Heart), here's how to turn two ellipses into two hearts. Happy Valentine's Day!
* Fun w/SAS ODS Graphics: Total Ellipse of the Heart (Two Tilted Ellipses = Two Hearts)
SAS implementation of Amanda Newton's clever "The Heart of Mathematics (Valentine's Day Heart)"
http://jwilson.coe.uga.edu/EMAT6680Su10/Newton/emat6690/Hearts/Hearts.html;
data heart; * Display "Happy Valentine's Day at (0,0);
retain x y 0 msg "HAPPY*VALENTINE'S*DAY!";
proc sgplot data=heart noborder nowall noautolegend aspect=1; * Plot two intersecting ellipses at +/- 45 degrees to make upright and upside-down hearts;
ellipseparm semimajor=1 semiminor=.6 / slope=1 xorigin=0 yorigin=0 lineattrs=(color=red) lineattrs=(thickness=3pt) nofill fillattrs=(color=cxC3540C); * Ellipse 1, angled at 45 degrees;
ellipseparm semimajor=1 semiminor=.6 / slope=-1 xorigin=0 yorigin=0 lineattrs=(color=red) lineattrs=(thickness=3pt) nofill fillattrs=(color=cxC3540C); * Ellipse 2, angled at -45 degrees;
text x=x y=y text=msg / textattrs=(size=22pt weight=bold color=red) splitchar='*' splitpolicy=splitalways contributeoffsets=none; * "Happy Valentine's Day!" message;
xaxis display=(nolabel noline noticks) values=(-1 to 1 by .5) valueattrs=(size=7pt color=blue) grid gridattrs=(color=lightblue) minorgrid minorgridattrs=(color=lightblue) minorcount=4;
yaxis display=(nolabel noline noticks) values=(-1 to 1 by .5) valueattrs=(size=7pt color=blue) grid gridattrs=(color=lightblue) minorgrid minorgridattrs=(color=lightblue) minorcount=4;
refline 0 / axis=x lineattrs=(color=blue thickness=1pt); * Reference lines thru (0,0);
refline 0 / axis=y lineattrs=(color=blue thickness=1pt); * Reference lines thru (0,0);
run;
Cute, as usual.
You use a different scaling than newton's article, so I just eyeballed the following enhancement to your graph. I think adding fill helps to see the heart inside of the ellipses:
data heart; * Display "Happy Valentine's Day at (0,0);
retain x y 0 msg "HAPPY*VALENTINE'S*DAY!";
do hx = -1.2 to 1.2 by 0.025;
do hy = -1 to 1.2 by 0.025;
if (hx**2 + hy**2 - hy*abs(hx) < 1) then do;
xx = 0.71*hx;
yy = 0.71*hy;
output;
end;
end;
end;
drop hx hy;
run;
title "Total Ellipse of the Heart";
proc sgplot data=heart noborder nowall noautolegend aspect=1; * Plot two intersecting ellipses at +/- 45 degrees to make upright and upside-down hearts;
scatter x=xx y=yy / markerattrs=(color=pink symbol=SquareFilled size=9);
ellipseparm semimajor=1 semiminor=.6 / slope=1 xorigin=0 yorigin=0 lineattrs=(color=red) lineattrs=(thickness=4pt) nofill fillattrs=(color=cxC3540C); * Ellipse 1, angled at 45 degrees;
ellipseparm semimajor=1 semiminor=.6 / slope=-1 xorigin=0 yorigin=0 lineattrs=(color=red) lineattrs=(thickness=4pt) nofill fillattrs=(color=cxC3540C); * Ellipse 2, angled at -45 degrees;
text x=x y=y text=msg / textattrs=(size=22pt weight=bold color=red) splitchar='*' splitpolicy=splitalways contributeoffsets=none; * "Happy Valentine's Day!" message;
xaxis display=(nolabel noline noticks) values=(-1 to 1 by .5) valueattrs=(size=7pt color=blue) grid gridattrs=(color=lightblue) minorgrid minorgridattrs=(color=lightblue) minorcount=4;
yaxis display=(nolabel noline noticks) values=(-1 to 1 by .5) valueattrs=(size=7pt color=blue) grid gridattrs=(color=lightblue) minorgrid minorgridattrs=(color=lightblue) minorcount=4;
refline 0 / axis=x lineattrs=(color=blue thickness=1pt); * Reference lines thru (0,0);
refline 0 / axis=y lineattrs=(color=blue thickness=1pt); * Reference lines thru (0,0);
run;
Cute, as usual.
You use a different scaling than newton's article, so I just eyeballed the following enhancement to your graph. I think adding fill helps to see the heart inside of the ellipses:
data heart; * Display "Happy Valentine's Day at (0,0);
retain x y 0 msg "HAPPY*VALENTINE'S*DAY!";
do hx = -1.2 to 1.2 by 0.025;
do hy = -1 to 1.2 by 0.025;
if (hx**2 + hy**2 - hy*abs(hx) < 1) then do;
xx = 0.71*hx;
yy = 0.71*hy;
output;
end;
end;
end;
drop hx hy;
run;
title "Total Ellipse of the Heart";
proc sgplot data=heart noborder nowall noautolegend aspect=1; * Plot two intersecting ellipses at +/- 45 degrees to make upright and upside-down hearts;
scatter x=xx y=yy / markerattrs=(color=pink symbol=SquareFilled size=9);
ellipseparm semimajor=1 semiminor=.6 / slope=1 xorigin=0 yorigin=0 lineattrs=(color=red) lineattrs=(thickness=4pt) nofill fillattrs=(color=cxC3540C); * Ellipse 1, angled at 45 degrees;
ellipseparm semimajor=1 semiminor=.6 / slope=-1 xorigin=0 yorigin=0 lineattrs=(color=red) lineattrs=(thickness=4pt) nofill fillattrs=(color=cxC3540C); * Ellipse 2, angled at -45 degrees;
text x=x y=y text=msg / textattrs=(size=22pt weight=bold color=red) splitchar='*' splitpolicy=splitalways contributeoffsets=none; * "Happy Valentine's Day!" message;
xaxis display=(nolabel noline noticks) values=(-1 to 1 by .5) valueattrs=(size=7pt color=blue) grid gridattrs=(color=lightblue) minorgrid minorgridattrs=(color=lightblue) minorcount=4;
yaxis display=(nolabel noline noticks) values=(-1 to 1 by .5) valueattrs=(size=7pt color=blue) grid gridattrs=(color=lightblue) minorgrid minorgridattrs=(color=lightblue) minorcount=4;
refline 0 / axis=x lineattrs=(color=blue thickness=1pt); * Reference lines thru (0,0);
refline 0 / axis=y lineattrs=(color=blue thickness=1pt); * Reference lines thru (0,0);
run;
Thaks @Rick_SAS - that is much better!
I made a note to myself to revisit this idea for Valentine's Day 2024. The result is this article:
The elliptical heart: https://blogs.sas.com/content/iml/2024/02/07/elliptical-heart.html
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.