BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
ChrisHemedinger
Community Manager

Do you remember last year when a SAS communities member asked for help in crafting a marriage proposal?  (No? Take minute to go read the thread -- it's worth it! )

 

The question and responses inspired us.  We know that SAS users, when given a challenge and the chance to help someone, rush to use their superpowers for Good.  And while "creating a marriage proposal" is probably not a business objective in your SAS life, the techniques learned along the way can have many uses other than just popping the question.

 "Binary heart" by @Rick_SAS"Binary heart" by @Rick_SASWith Valentine's Day is approaching (February 14 -- don't forget!), we'd like to channel that creativity and knowledge into a fun challenge: creating Valentine's Day greetings with SAS tools!  To participate, respond to this post with code and/or images of your SAS-generated Valentines.  It's not a contest -- not exactly -- but we'll definitely take the best submissions and do something fun with them.  And even if you don't have a Valentine to add, please click Like on any of the replies that you...well...like.

 

Looking for inspiration?

 

Remember, include your code (if applicable) -- use the code button (the SAS running man) to add/format it.  And add screenshots/images with the Photos button. 

 

 

(Communities tip: Try not to add file attachments if you can avoid it -- sometimes these are difficult for visitors to view.)

 

See also:

A Valentine Challenge: Express your ❤️ with SAS

 

Register for SAS Innovate 2025!! The premier event for SAS users, May 6-9 in Orlando FL. Sign up now for the best deals!
1 ACCEPTED SOLUTION

Accepted Solutions
ChrisHemedinger
Community Manager

Thanks to all for the wonderful contributions!  You all have demonstrated your romantic nerd skills admirably.

 

Thanks especially to @tc@Estelalutero@MichelleHomes@ghosh@Cowboy_Coffee@art297, @ptimusk@jl3@OliviaWright, and @chinki.

 

I've captured all of the entries in a gallery on the blog post.

 

gallery.png

Register for SAS Innovate 2025!! The premier event for SAS users, May 6-9 in Orlando FL. Sign up now for the best deals!

View solution in original post

33 REPLIES 33
MichelleHomes
Meteorite | Level 14

Inspired by the many great Valentines day posts I thought I'd create a variation of @GraphGuy's traditional SAS/GRAPH PROC GMAP Heart and dust off my annotate skills to create the following...

 

valentine-pi.png

 

Code below...

 

%let name=valentines_graph;
filename odsout '.';

%let pink=cxFF3333;
%let darkgray=gray66;

data heart_data;
do x=-2 to 2 by .05;
 y=sqrt(1-(abs(x)-1)**2);
 output;
 end;
do x=2 to -2 by -.05;
 y=arcos(1-abs(x))-3.14;
 output;
 end;
run;

data heart_data; set heart_data;
/* set the undefined values to zero */
if y=. then y=0;
/* re-shape the deep parts of the 'V' just a tiny bit */
if round(x*100)=0 then y=y+.2;
/* an id variable for gmap */
idvar='heart';
my_html=
 'title='||quote('I Love SAS!')||
 ' href='||quote('https://blogs.sas.com/content/sgf/2018/01/22/sas-language-valentines/');;
run;

data anno_pi;
length function $8;
xsys='2'; ysys='2'; hsys='3'; when='a'; color="&darkgray";
function='move'; x=-0.75; y=-1.25; output;
function='draw'; x=-0.75; y=0.0; output;
function='move'; x=-1.25; y=0.0; output;
function='draw'; x=1.25; y=0.0; output;
function='move'; x=0.75; y=0.0; output;
function='draw'; x=0.75; y=-1.25; output;
run;
goptions device=png;
goptions noborder;

ODS LISTING CLOSE;
ODS HTML path=odsout body="&name..htm"
 (title="Valentine's Heart SAS Graph") style=htmlblue;

goptions gunit=pct ftitle='albany amt/bold' ftext='albany amt/bold' htitle=3.5 htext=3.5 ctext=&darkgray;

title1 ls=1.5  c=&darkgray "My " c=&pink "love" c=&darkgray " for you";
title2 ls=1.5  c=&darkgray "is like the decimals of pi";
footnote ls=1.5  c=&darkgray bold "...never ending";
*title2 h=8 ' ';
pattern1 v=s c=&pink;
proc gmap data=heart_data map=heart_data anno=anno_pi;
id idvar;
choro idvar / nolegend
 coutline=&darkgray
 html=my_html
 des='' name="&name";
run;

quit;
ODS HTML CLOSE;
ODS LISTING;

Cheers,

Michelle

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

Here's my stab at this challenge, featuring little misshapen hearts made out of scatter plot dots. ❤️

 

Love Over Time.png 

And here's the code:

data love;
	input time love;
datalines;
0 0 
1 1 
1.12 1.12
.88 1.12
2 2 
3 3 
3.12 3.12
2.88 3.12
4 4 
5 5 
5.12 5.12
4.88 5.12
6 6 
7 7 
7.12 7.12
6.88 7.12
8 8 
9 9 
9.12 9.12
8.88 9.12
10 10 
11 11 
11.12 11.12
10.88 11.12
12 12 
13 13 
13.12 13.12
12.88 13.12
14 14 
15 15 
15.12 15.12
14.88 15.12
16 16 
17 17 
17.12 17.12
16.88 17.12
18 18 
19 19 
;
run;

proc template;
define statgraph sgdesign;
dynamic _TIME2 _LOVE;
begingraph / designwidth=629 designheight=482;
   entrytitle halign=center 'Love Over Time' / textattrs=(family='Monotype Corsiva' size=24 );
   layout lattice / rowdatarange=data columndatarange=data rowgutter=10 columngutter=10;
      layout overlay / wallcolor=CXFFCCCC xaxisopts=( label=('TIME') labelattrs=(family='HeiT' size=16 ) linearopts=( tickvaluepriority=TRUE tickvalueformat=BEST6.)) yaxisopts=( label=('LOVE') labelattrs=(family='HeiT' size=16 ) linearopts=( tickvaluepriority=TRUE tickvalueformat=BEST6.));
         scatterplot x=_TIME2 y=_LOVE / name='scatter' markerattrs=(color=CXFF0000 symbol=CIRCLEFILLED size=7 weight=bold );
      endlayout;
   endlayout;
endgraph;
end;
run;

proc sgrender data=WORK.LOVE template=sgdesign;
dynamic _TIME2="TIME" _LOVE="LOVE";
run;
Jay54
Meteorite | Level 14

Interesting idea to use the Circlefilled symbol to create a heart. Smiley Happy

The Symbol font has a "Heart" shape (0xA9).  Another way would be to use SYMBOLCHAR to define a heart symbol to use it directly

OliviaWright
SAS Employee

Ha ha.. With this challenge I took a "word harder, not smarter" approach.. That's the saying right?:)

I was using ODS Graphics Designer which sadly does not have a heart as a symbol option. But I will take this into consideration for my next valentine. 🙂

jl3
Pyrite | Level 9 jl3
Pyrite | Level 9
data val;
Infile Datalines;
informat vert 2. horz 2.;
input vert horz;

Datalines;
1 6
2 5
2 6
2 7
3 4
3 5
3 6
3 7
3 8
4 3
4 4
4 5
4 6
4 7
4 8
4 9
5 2
5 3
5 4
5 5
5 6
5 7
5 8
5 9
5 10
6 1
6 2
6 3
6 4
6 5
6 6
6 7
6 8
6 9
6 10
6 11
7 1
7 2
7 3
7 4
7 5
7 6
7 7
7 8
7 9
7 10
7 11
8 1
8 2
8 3
8 4
8 5
8 6
8 7
8 8
8 9
8 10
8 11
9 2
9 3
9 4
9 5
9 6
9 7
9 8
9 9
9 10
10 3
10 4
10 5
10 7
10 8
10 9
11 4
11 8
run;

options pageno=1 linesize=min pagesize=35;

proc plot data=val;
plot vert*horz='v' /vpos=27;
run;
ChrisHemedinger
Community Manager

That's old school, @jl3!  I've taken the liberty of posting the output.

 

 vert |
      |
      |
      |
      |
   11 +                 v                   v
      |
   10 +            v    v    v         v    v    v
      |
    9 +       v    v    v    v    v    v    v    v    v
      |
    8 +  v    v    v    v    v    v    v    v    v    v    v
      |
    7 +  v    v    v    v    v    v    v    v    v    v    v
      |
    6 +  v    v    v    v    v    v    v    v    v    v    v
      |
    5 +       v    v    v    v    v    v    v    v    v
      |
    4 +            v    v    v    v    v    v    v
      |
    3 +                 v    v    v    v    v
      |
    2 +                      v    v    v
      |
    1 +                           v
      |
      ---+----+----+----+----+----+----+----+----+----+----+--
         1    2    3    4    5    6    7    8    9   10   11
Register for SAS Innovate 2025!! The premier event for SAS users, May 6-9 in Orlando FL. Sign up now for the best deals!
tc
Lapis Lazuli | Level 10 tc
Lapis Lazuli | Level 10

LOVE.gif

 

With apologies to Robert Indiana, here's a simple SAS ODS Graphics-generated valentine! Smiley Happy Heart

 

* Fun w/SAS ODS Graphics: Valentine's Day L-O-V-E;

data love1;                         * Letters L-V-E in upper left, lower left/right quadrants;
x1=1; y1=2; txt1='L'; n+1; output;
x1=1; y1=1; txt1='V'; n+1; output;
x1=2; y1=1; txt1='E'; n+1; output;

data love2;                         * Unicode heart ("O") in upper right quadrant;
x2=1.9; y2=1.95; txt2=unicode('\u2764'); output;

data love3;                         * Valentine message in center of heart;
x3=1.9; y3=1.95; txt3="BE*MINE"; output;

data love4;                         * Points for filled polygons for each quadrant;
input id@; do i=1 to 4; input x4 y4@; output; end;
cards;
1 0 1.53 1.5 1.53 1.5 3 0 3 "L"
2 1.5 1.53 3 1.53 3 3 1.5 3 "O"
3 0 0 1.5 0 1.5 1.53 0 1.53 "V"
4 1.5 0 3 0 3 1.53 1.5 1.53 "E"
;
data love;                          * Put it all together;
set love1 love2 love3 love4;
                                    * Plot a Valentine!;
ods graphics on / reset=index imagefmt=gif antialias height=5in width=5in;  
proc sgplot data=love noautolegend noborder pad=0 aspect=1;
* 1. Colored quadrants (use transparency to create lighter version of letter colors);
polygon x=x4 y=y4 id=id / colormodel=(blue red green orange) transparency=.85 nooutline fill colorresponse=id;
* 2. L-V-E letters;
text x=x1 y=y1 text=txt1 / position=center vcenter=bbox contributeoffsets=none colormodel=(blue green orange)
                           textattrs=(family="Cumberland AMT" size=258pt weight=bold) colorresponse=n; 
* 3. "Outer" heart ("O" letter), tilted;
text x=x2 y=y2 text=txt2 / position=center vcenter=bbox contributeoffsets=none rotate=-45
                           textattrs=(family="Arial Unicode MS" size=202pt weight=bold color=red); 
* 4. Smaller "inner" heart (inside "O" letter), tilted;
text x=x2 y=y2 text=txt2 / position=center vcenter=bbox contributeoffsets=none rotate=-45 
                           textattrs=(family="Arial Unicode MS" size=106pt weight=bold color=pink); 
* 5. "BE MINE" message on "inner" heart, tilted;
text x=x3 y=y3 text=txt3 / position=center vcenter=bbox contributeoffsets=none splitchar='*' splitpolicy=splitalways
                           textattrs=(size=14pt weight=bold color=red) rotate=-45; 
xaxis display=none offsetmin=0 offsetmax=0 values=(.5 2.45); * Suppress labels/ticks on axes, set bounds;
yaxis display=none offsetmin=0 offsetmax=0 values=(.5 2.55);  

 

Jay54
Meteorite | Level 14

Awesome and very creative and aesthetic.  Nice to see you make this visual using SGPLOT with fairly compact code.

chinki
Fluorite | Level 6
data data1;
input love time_year age;
datalines;
10 1 20 
11 2 21
12 3 22
13 4 23
14 5 24
15 6 25
16 7 26
17 8 27
18 9 28
19 10 29
20 11 30
;

run;
ods pdf file='C:\Users\**bleep**\Google Drive\Computational Statistics\work1.pdf';
title "SAS Valentine";
proc g3d;
scatter love*time_year=age / color='red'  shape='HEART'  size=3 ctext='red'  caxis='red' ;
run;
quit;
ods pdf close;

sas.jpg

MichelleHomes
Meteorite | Level 14

LOVEly chart @chinkiHeart It's also lovely to see that you're a new SAS Support Communities member. May your initiative encourage others. Yeah!

 

Kind Regards,

Michelle

P.S. Participation in the community is a great way to earn some SAS Global Forum 2018 conference swag!

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

Thank you! Michelle 

Yes, I am new to this community and enjoying SAS.

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

mmValentine.png 

 

To paraphrase Bobby Hill, "After seeing @Rick_SAS's Binary Heart and M&Ms posts, well, what was I supposed to do? Not code a SAS ODS Graphics I-Heart-M&Ms Valentine?" Smiley Happy

 

* Fun w/SAS ODS Graphics: I Heart M&Ms Valentine;

data red(keep=x y m s rename=(x=x1 y=y1)) white(keep=x y m s rename=(x=x2 y=y2));
retain m "m" s 1;                  * M&M letter ("m"), M&M size (1);
do y=15 to 1 by -1;                * Read in 15x15 M&M valentine layout template from inline data;
  input mms $15.;                  * X=Background M&M (red), *=Heart M&M (white);
  do x=1 to 15;                    * Output points for plot;                 
    if substr(mms,x,1)="X" then output red; 
    else output white;
  end;
end;   
cards;
XXXXXXXXXXXXXXX
XXXXXXXXXXXXXXX
XXX***XXX***XXX
XX*****X*****XX
X*************X
X*************X
X*************X
XX***********XX
XXX*********XXX
XXXX*******XXXX
XXXXX*****XXXXX
XXXXXX***XXXXXX
XXXXXXX*XXXXXXX
XXXXXXXXXXXXXXX
XXXXXXXXXXXXXXX
;
data mms;                          * Put M&Ms all together;
set red white;
                                   * Plot M&Ms valentine!;
ods graphics on / reset=index imagefmt=png antialias=on height=5in width=5in dataskinmax=500;  
proc sgplot data=mms noautolegend noborder pad=0 aspect=1 nowall subpixel;
styleattrs backcolor=rose;
* 1. Background M&Ms (red);
bubble x=x1 y=y1 size=s / dataskin=gloss bradiusmin=15 fill fillattrs=(color=red);
text x=x1 y=y1 text=m / textattrs=(family="Albany AMT Bold" size=12pt color=white weight=bold) position=center vcenter=bbox contributeoffsets=none strip;
* 2. Heart M&Ms (white);
bubble x=x2 y=y2 size=s / dataskin=gloss bradiusmin=15 fill fillattrs=(color=white);
text x=x2 y=y2 text=m / textattrs=(family="Albany AMT Bold" size=12pt color=deeppink weight=bold) position=center vcenter=bbox contributeoffsets=none strip;
xaxis display=none offsetmin=0 offsetmax=0 min=.4 max=15.6 values=(.4 15.6); * Suppress labels/ticks on axes, set bounds;
yaxis display=none offsetmin=0 offsetmax=0 min=.4 max=15.6 values=(.4 15.6);
MichelleHomes
Meteorite | Level 14

Awwww @tc... so glad you did! A magnificent map of m&ms 😍

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

SAS Innovate 2025: Register Now

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!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 33 replies
  • 10898 views
  • 164 likes
  • 14 in conversation