BookmarkSubscribeRSS Feed
LizGagne
Obsidian | Level 7

I'm trying to use the following code to replicate XKCD's Binary Heart comic:

 

/* generate random binary heart similar to xkcd comic: http://xkcd.com/99/ */
data BinaryHeart;
drop Nx Ny t r;
Nx = 21; Ny = 23;
call streaminit(2142015);
do x = -2.6 to 2.6 by 5.2/(Nx-1);
do y = -4.4 to 1.5 by 6/(Ny-1);
/* convert (x,y) to polar coordinates (r, t) */
r = sqrt( x**2 + y**2 );
t = atan2(y,x);
/* eqn: blogs.sas.com/content/iml/2011/02/14/a-parametric-view-of-love/ */
Heart= (r < 2 - 2*sin(t) + sin(t)*sqrt(abs(cos(t))) / (sin(t)+1.4)) 
& (y > -3.5);
B = rand("Bernoulli", 0.5);
output;
end;
end;
run;

ods graphics / width=400px height=500px;
title "Happy Valentine's Day";
proc sgplot data=BinaryHeart noautolegend;
styleattrs datacontrastcolors=(lightgray red); 
scatter x=x y=y / group=Heart markerchar=B markercharattrs=(size=10);
xaxis display=none offsetmin=0 offsetmax=0.06;
yaxis display=none;
run;

 

I'd love to swap out the random binary for a specific binary string, but can't quite figure out the spacing. When I use the following, all the numbers overlap, but when I try to add spacing I get an error that SAS was expecting an arithmetic operator.

 

/* generate random binary heart similar to xkcd comic: http://xkcd.com/99/ */
data BinaryHeart;
drop Nx Ny t r;
Nx = 21; Ny = 23;
call streaminit(2142015);
do x = -2.6 to 2.6 by 5.2/(Nx-1);
do y = -4.4 to 1.5 by 6/(Ny-1);
/* convert (x,y) to polar coordinates (r, t) */
r = sqrt( x**2 + y**2 );
t = atan2(y,x);
/* eqn: blogs.sas.com/content/iml/2011/02/14/a-parametric-view-of-love/ */
Heart= (r < 2 - 2*sin(t) + sin(t)*sqrt(abs(cos(t))) / (sin(t)+1.4)) 
& (y > -3.5);
B=(0110110101101111011011000110110001111001);
output;
end;
end;
run;

ods graphics / width=400px height=500px;
title "Happy Valentine's Day";
proc sgplot data=BinaryHeart noautolegend;
styleattrs datacontrastcolors=(lightgray red); 
scatter x=x y=y / group=Heart markerchar=B markercharattrs=(size=10);
xaxis display=none offsetmin=0 offsetmax=0.06;
yaxis display=none;
run;
1 REPLY 1
PGStats
Opal | Level 21

I guess you want to cycle on the elements of your binary string, like this:

 

/* generate random binary heart similar to xkcd comic: http://xkcd.com/99/ */
data BinaryHeart;
drop Nx Ny t r i;
length B $1;
Nx = 21; Ny = 23;
*call streaminit(2142015);
i = 0;
str = "0110110101101111011011000110110001111001";
do x = -2.6 to 2.6 by 5.2/(Nx-1);
    do y = -4.4 to 1.5 by 6/(Ny-1);
        /* convert (x,y) to polar coordinates (r, t) */
        r = sqrt( x**2 + y**2 );
        t = atan2(y,x);
        /* eqn: blogs.sas.com/content/iml/2011/02/14/a-parametric-view-of-love/ */
        Heart= (r < 2 - 2*sin(t) + sin(t)*sqrt(abs(cos(t))) / (sin(t)+1.4)) 
        & (y > -3.5);
        *B = rand("Bernoulli", 0.5);
        B = substr(str, 1+mod(i,length(str)), 1);
        i + 1;
        output;
        end;
    end;
run;

ods graphics / width=400px height=500px;
title "Happy Valentine's Day";
proc sgplot data=BinaryHeart noautolegend;
styleattrs datacontrastcolors=(lightgray red); 
scatter x=x y=y / group=Heart markerchar=B markercharattrs=(size=10);
xaxis display=none offsetmin=0 offsetmax=0.06;
yaxis display=none;
run;

SGPlot2.png

 

 

Playing with the length of the binary string will generate different patterns.

PG

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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
  • 1 reply
  • 979 views
  • 0 likes
  • 2 in conversation