Hello,
I am new to developing graphs in SAS. The following graphs do not exist in SAS.
.Donuts of Pie
Can you please advise me of the best way to create the following types of graph because I am not sure how to begin?
An example will be very helpful.
I really appreciate your advice. Thank you.
You can submit code for other languages from SAS.
If you can create these examples of Pie Charts in other systems (language + graphing library), what are they and their coding ?
SAS can generate source code for the other system and submit it in order to produce the output.
In the past the Data Step Graphics Interface (DSGI) would let you draw anything you wanted using the Base Graph driver, however, the output images are not as polished looking as statistical graphics (SG) produced output. Also, DSGI became unsupported (i.e hidden legacy with no documentation, just a step above deprecated) in 9.4. DSGI still works but you get scary message in log.
Today you can use SG Annotation to markup SGPLOT SGPIE output, or render a scratch drawing of SGANNO available functions presented through a custom template (GTL) played by SGRENDER TEMPLATE= SGANNO=. The current downside is that the SGANNO function dictionary has a limited set of graphics operations compared to DSGI. Some features SGANNO is missing are ARC and PIE functions -- so doing SAS coding to produce SG output according to your new pie design might be arduous at best.
Hi Kavita,
without any sample data, we can only suggest. Your can look at the explode option for pie charts. Also GTL gives you the tools for pretty sophisticated graphs.
Please take a loot at this paper for ways to approach your problem
https://support.sas.com/resources/papers/proceedings/pdfs/sgf2008/071-2008.pdf
For the second graph:
1. Make a pie as per your code, and use option invible= as shown in the paper linked by @ghosh to free the space for the donut plot
2. Make a donut chart to plot the donut data
3. Use proc greplay to superimpose the two charts, pie on top.
Unsure what you mean, but you probably need to use an annotate data set to draw custom lines.
My apologies, I have not had the time to follow up. I am not sure how you would draw those lines. I have a feeling if you got the example from a publication, it was likely drawn in an image editing software
You can position your graphs as wanted. See https://support.sas.com/kb/44/973.html for example.
proc format;
value $fmt(default=80)
'Very Heavy (> 25)','Moderate (6-15)','Light (1-5)'=' other'; /*add a white blank before 'other' is to make 'other' appeared at first place in PERCENT_MAIN dataset*/
run;
data have;
set sashelp.heart(keep=Smoking_Status rename=(Smoking_Status=type) where=(type is not missing));
category=put(type,$fmt.);
run;
proc freq data=have noprint order=internal;
table category/out=percent_main; /*get main pie percent*/
table category*Type/out=percent_all; /*get sub pie percent*/
run;
/*process main pie*/
data main_temp;
set percent_main;
PERCENT=0.01*PERCENT;
if _n_=1 then percent_cum=PERCENT/2; /*when category='other'*/
else percent_cum+PERCENT;
keep category percent_cum PERCENT;
format PERCENT percent8.2;
run;
data main_pie;
set main_temp;
pi=constant('pi');
lag_percent_cum=lag(percent_cum);
label=catx('|',category,put(PERCENT,percent8.2));
id=_n_;x=0;y=0;output;
if _n_=1 then do; /*when category='other'*/
do theta=-2*pi*percent_cum to 2*pi*percent_cum by 0.001;
x=cos(theta);y=sin(theta); output;
end;
end;
else do;
do theta=2*pi*lag_percent_cum to 2*pi*percent_cum by 0.001;
x=cos(theta);y=sin(theta); output;
end;
end;
keep category id x y PERCENT label;
run;
/*Keep line position1*/
data line_pos1(rename=(id=line_id x=line_x y=line_y));
set main_pie(where=(id=1 and x ne 0)) end=last;
if _n_=1 or last ;
keep id x y;
run;
/*process sub pie*/
proc sql;
create table sub_temp as
select type,0.01*PERCENT as PERCENT format=percent8.2,
sum(calculated PERCENT) as sum_percent,calculated sum_percent/2 as half_percent
from percent_all
where strip(category)='other';
quit;
data sub_pie;
set sub_temp(rename=(type=category) );
pi=constant('pi');
id=10000+_n_;
cum_percent+PERCENT;
lag_cum_percent=coalesce(lag(cum_percent),0);
label=catx('|',category,put(PERCENT,percent8.2));
do theta=-2*pi*half_percent+2*pi*lag_cum_percent to -2*pi*half_percent+2*pi*cum_percent by 0.001;
flag=1;x=1.5*cos(theta);y=1.5*sin(theta); output;
end;
do theta=-2*pi*half_percent+2*pi*cum_percent to -2*pi*half_percent+2*pi*lag_cum_percent by -0.001;
flag=2;x=2*cos(theta);y=2*sin(theta); output;
end;
keep category id x y PERCENT label flag;
run;
/*Keep line position2*/
data line_pos2(rename=(id=line_id x=line_x y=line_y));
set sub_pie;
by id flag;
if first.flag or last.flag;
keep id x y flag;
run;
data line_pos22;
set line_pos2 ;
if _n_=1;
run;
data line_pos2_temp;
set line_pos2(where=(flag=2)) ;
by line_id;
if first.line_id;
run;
data line_pos23;
set line_pos2_temp end=last;
if last;
run;
data line_pos3;
set line_pos22 line_pos23;
drop flag;
run;
/*Keep line position all*/
data line_pos(rename=(id=line_id));
id+1;
set line_pos1;output;
set line_pos3;output;
drop line_id;
run;
/*Plot pie of pie chart*/
data pie;
length category $ 200;
set main_pie sub_pie line_pos;
run;
ods graphics/noborder ANTIALIAS ANTIALIASMAX=10000000 width=800px height=600px;
proc sgplot data=pie aspect=1.1 noautolegend noborder;
series x=line_x y=line_y/group=line_id lineattrs=(color=black pattern=dash);
polygon id=id x=x y=y/group=category label=label labelattrs=(color=black size=12) fill nooutline dataskin=sheen
LABELLOC=INSIDEBBOX LABELPOS=CENTER name='x' splitchar='|' ;
xaxis display=none;
yaxis display=none;
run;
proc format;
value $fmt(default=80)
'Very Heavy (> 25)','Moderate (6-15)','Light (1-5)'=' other'; /*add a white blank before 'other' is to make 'other' appeared at first place in PERCENT_MAIN dataset*/
run;
data have;
set sashelp.heart(keep=Smoking_Status rename=(Smoking_Status=type) where=(type is not missing));
category=put(type,$fmt.);
run;
proc freq data=have noprint order=internal;
table category/out=percent_main; /*get main pie percent*/
table category*Type/out=percent_all; /*get sub pie percent*/
run;
/*process main pie*/
data main_temp;
set percent_main;
PERCENT=0.01*PERCENT;
if _n_=1 then percent_cum=PERCENT/2; /*when category='other'*/
else percent_cum+PERCENT;
keep category percent_cum PERCENT;
format PERCENT percent8.2;
run;
data main_pie;
set main_temp;
pi=constant('pi');
lag_percent_cum=lag(percent_cum);
label=catx('|',category,put(PERCENT,percent8.2));
id=_n_;x=0;y=0;output;
if _n_=1 then do;
do theta=-2*pi*percent_cum to 2*pi*percent_cum by 0.001;
x=cos(theta);y=sin(theta); output;
end;
end;
else do;
do theta=2*pi*lag_percent_cum to 2*pi*percent_cum by 0.001;
x=cos(theta);y=sin(theta); output;
end;
end;
keep category id x y PERCENT label ;
run;
/*process sub pie*/
proc sql;
create table sub_temp as
select type,0.01*PERCENT as PERCENT format=percent8.2,
sum(calculated PERCENT) as sum_percent,calculated sum_percent/2 as half_percent
from percent_all
where strip(category)='other';
quit;
data sub_pie;
set sub_temp(rename=(type=category) );
pi=constant('pi');
id=10000+_n_;
cum_percent+PERCENT;
lag_cum_percent=coalesce(lag(cum_percent),0);
label=catx('|',category,put(PERCENT,percent8.2));
do theta=-2*pi*half_percent+2*pi*lag_cum_percent to -2*pi*half_percent+2*pi*cum_percent by 0.001;
x=0.5*cos(theta);y=0.5*sin(theta); output;
end;
do theta=-2*pi*half_percent+2*pi*cum_percent to -2*pi*half_percent+2*pi*lag_cum_percent by -0.001;
x=cos(theta);y=sin(theta); output;
end;
keep category id x y PERCENT label ;
run;
/*Plot pie of pie chart*/
data pie;
length category $ 200;
set main_pie(where=(id ne 1)) sub_pie ;
run;
ods graphics/noborder ANTIALIAS ANTIALIASMAX=10000000 width=800px height=600px;
proc sgplot data=pie aspect=1 noautolegend noborder;
polygon id=id x=x y=y/group=category label=label labelattrs=(color=black size=12) fill nooutline dataskin=sheen
LABELLOC=INSIDEBBOX LABELPOS=CENTER name='x' splitchar='|' ;
xaxis display=none;
yaxis display=none;
run;
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!
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.