BookmarkSubscribeRSS Feed
Kavita21K
Fluorite | Level 6

Hello,

 

I am new to developing graphs in SAS. The following graphs do not exist in SAS.

.Donuts of PieDonuts of PieGraphs-and-Chatrs-Pie-Chart-Donut-Chart-Template

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.

12 REPLIES 12
RichardDeVen
Barite | Level 11

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.

ghosh
Barite | Level 11

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

Kavita21K
Fluorite | Level 6
thank you. Here is some sample code:
goptions reset=all colors=(cx7c95ca cxde7d6f cx66ada0 cxb689cd cxa9865b cxbabc5c);

data information;
input section $ country $ total;
datalines;
1 Germany 102
1 Greece 102
1 Iceland 107
1 Ireland 177
1 Italy 303
2 France 53
2 Finland 42
2 Denmark 41
2 Belgium 38
2 Austria 36
;.
proc sort;
by total;
proc gchart;
pie section/value = outside discrete freq=total value=inside
noheading coutline=black detail=country
detail_percent=best
detail_value=none
detail_slice=best
detail_threshold=2
legend discrete freq=total value=inside
noheading coutline=black;
pattern1 color=ROSE ;
pattern2 color=OLIVE ;
pattern3 color=LIGB ;
run;
quit;

Can you please let me know how I can draw a donut with the pie and extend it with dashed lines?

Thank you for your help.
ChrisNZ
Tourmaline | Level 20

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.

Kavita21K
Fluorite | Level 6
Thank you so much! Only one last question is how do I draw 2 lines from one graph to the other as shown in my example?
ChrisNZ
Tourmaline | Level 20

Unsure what you mean, but you probably need to use an annotate data set to draw custom lines.

ghosh
Barite | Level 11

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 

Kavita21K
Fluorite | Level 6
Also, how can you align 2 charts with proc greplay if I wanted to move 1 of the images more to the left or right?
ChrisNZ
Tourmaline | Level 20

You can position your graphs as wanted. See https://support.sas.com/kb/44/973.html for example.

Ksharp
Super User
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;

Ksharp_0-1728972781465.png

 

Ksharp
Super User
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;

Ksharp_0-1728973661311.png

 

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
  • 12 replies
  • 5762 views
  • 10 likes
  • 5 in conversation