BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
lbarwick
Quartz | Level 8

Morning,

 

I'm trying to use proc gchart in conjunction with the annotation facility to generate a stacked bar graph with a table annotated below. An example of my desired result is below (produced in Excel):

 

desired_result.PNG

The closest example I found was at http://support.sas.com/kb/35/774.html so this is what I modeled my code off of. I did get my data set up and was able to make the example code work and produce a graph similar to what is in the preceding link (two bars per response variable with the actual response values displayed in a grid under the bar graph). That result is below:

 

initial_result.PNG

I then began adjusting my code to create stacked bars and got my table frame and legend set up appropriately. The issue I am running into now is that the response values are scrunched to the left of my annotated table (see highlighted portion):

initial_stacked.PNG

My code is below. This is not complete (i.e. the pieces that define the raw data behind the graph are not included for brevity). I mainly need help with the /*Populate the table */ portion and curious if anyone sees anything obvious that I need to adjust to get my data annotations correctly displayed in the table. Or perhaps my gchart code is not set up correctly to do what I want. If needed I can re-post code to facility reproducibility.

data impact&spectype._forprint;
	length mid $15.;
   set impact&spectype._forprint;
	if dx ne 'Total' then do;
   response=&spectype.totreq; mid='totreq'; output; *use to display N in annotated data;
   response=totremain; mid='totremain'; output; *use to display N in annotated data;
	response=pctrequest; mid='pctrequest'; output; *use for % in y-axis of stacked bar;
	response=pctremain; mid='pctremain'; output; *use for % in y-axis of stacked bar;
	end;

keep dx response mid totremain &spectype.totreq pctrequest pctremain n;
run;
proc sort; by dx mid; run;

data impact&spectype._anno;
   set impact&spectype._forprint;
   by dx mid;
   length function color $8 text $20 style $ 20;

/* Populate the table */
   if first.dx then do;
      function='move'; xsys='2'; ysys='1';
         midpoint=mid; group=dx; y=0;
         output;
      function='cntl2txt'; output;
      function='label'; xsys='A'; ysys='3';
         x=+3; y=17.25;
         text=trim(left(put(&spectype.totreq,8.1)));
         color='black'; position='+'; when='a';
         output;
      function='move'; xsys='2'; ysys='1';
         midpoint=mid; group=dx; y=0;
         output;
      function='cntl2txt'; output;
      function='label'; xsys='A'; ysys='3';
         x=+3; y=13.75;
         text=trim(left(put(totremain,8.1)));
         color='black'; position='+'; when='a';
         output;
   end;

/* Generate the table frame */                                                                                                          
   function='move'; xsys='3'; ysys='3';                                                                                                 
      x=3; y=12;                                                                                                                         
      output;                                                                                                                           
   function='bar';  xsys='1'; ysys='3';                                                                                                 
      x=100; y=19;                                                                                                                      
      style='empty'; color='black'; line=0;                                                                                             
      output;                                                                                                                           
                                                                                                                                        
/* Generate the row headers */                                                                                                          
   function='label'; xsys='3'; ysys='3';                                                                                                
      style='marker'; text='U'; color='cxde7e6f';                                                                                       
      x=4; y=17.25; position='6';                                                                                                          
      output;                                                                                                                           
   function='label'; xsys='3'; ysys='3';                                                                                                
      style="Albany AMT"; text='Total requested'; color='black';                                                                          
      x=7; y=17.5; position='6';                                                                                                          
      output;                                                                                                                           
   function='label'; xsys='3'; ysys='3';                                                                                                
      style='marker'; text='U'; color='cx7c95ca';                                                                                       
      x=4; y=13.75; position='6';                                                                                                         
      output;                                                                                                                           
   function='label'; xsys='3'; ysys='3';                                                                                                
      style="Albany AMT"; text='Total remaining'; color='black';                                                                              
      x=7; y=14; position='6';                                                                                                           
      output;                                                                                                                           
                                                                                                                                        
/* Generate the vertical lines in the table */                                                                                          
   function='move'; xsys='1'; ysys='1';                                                                                                 
      x=0; y=0;                                                                                                                         
      output;                                                                                                                           
   function='draw'; xsys='1'; ysys='3';                                                                                                 
      x=0; y=12;                                                                                                                         
      line=1; color='black';                                                                                                            
      output;                                                                                                                           
   function='move'; xsys='1'; ysys='1';                                                                                                 
      x=100; y=0;                                                                                                                       
      output;                                                                                                                           
   function='draw'; xsys='1'; ysys='3';                                                                                                 
      x=100; y=12;                                                                                                                       
      line=1; color='black';                                                                                                            
      output;
                                                                                                                           
                                                                                                                                        
/* Generate the horizontal line in the table */                                                                                         
   function='move'; xsys='3'; ysys='3';                                                                                                 
      x=3; y=15.5;                                                                                                                      
      output;                                                                                                                           
   function='draw'; xsys='1'; ysys='3';                                                                                                 
      x=100; y=15.5;                                                                                                                    
      line=1; color='black';                                                                                                            
      output;                                                                                                                           
run;    

%mend impact;
%impact (spectype=frozen);

ods graphics;

title1 font='arial' height=10pt "Total frozen aliquots requested for R050, by final clinical diagnosis";                                                                                     
                                                                                                                                        
axis1 label=(a=90 '% Aliquots')                                                                                                 
      order=(80 to 100 by 2)                                                                                                          
      minor=none;                                                                                                                       
                                                                                                                                        
axis2 label=none                                                                                                                        
      value=none                                                                                                                        
      origin=(20pct,22pct)                                                                                                              
      offset=(4pct,4pct);                                                                                                               
                                                                                                                                        
axis3 label=none;                                                                                                                       
                                                                                                                                        
footnote1 h=.5 '  ';                                                                                                                    

pattern1 value=solid color=cx7c95ca;                                                                                                    
pattern2 value=solid color=cxde7e6f;                                                                                                    

ods pdf file="X:\XXX\COMMON\Requests\test.pdf";

proc gchart data=impactfrozen_forprint (where=(mid in ('pctremain','pctrequest')));                                                                                                                   
   vbar dx / sumvar=response subgroup=mid group=dx g100 nozero
              coutline=black                                                                                         
              space=0 gspace=5 width=4                                                                                                  
              cframe=white autoref clipref                                                                                             
              raxis=axis1 maxis=axis2 gaxis=axis3 nolegend
              annotate=impactfrozen_anno; 

run; quit;  
ods pdf close;

 

1 ACCEPTED SOLUTION

Accepted Solutions
GraphGuy
Meteorite | Level 14

Here's one way to do it with gchart and annotate:

 

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

goptions device=png;
goptions border;
 
ODS LISTING CLOSE;
ODS HTML path=odsout body="&name..htm" style=htmlblue;

goptions gunit=pct htitle=6 ftitle="albany amt/bold" htext=4.25 ftext="albany amt";
gopitons ctext=gray33;

data dx;
input nmid $ pctmid $ dx $ nresponse pctresponse;
datalines;
totreq pctreq COPD 18 0.20
totrem pctrem COPD 8800 99.80
totreq pctreq Control 5 0.52
totrem pctrem Control 949 99.48
totreq pctreq ILD 0 0
totrem pctrem ILD 8124 100
totreq pctreq Other 200 12.93
totrem pctrem Other 1546 87.07
;
run;

data dx; set dx;
format pctresponse percentn7.0;
pctresponse=pctresponse/100;
run;

data anno_values; set dx;
xsys='2'; ysys='3'; hsys='3'; when='a';
function='label'; position='5'; 
xc=dx; 
if nmid='totreq' then do;
 y=15; 
 text=trim(left(nresponse));
 output;
 end;
if nmid='totrem' then do;
 y=7; 
 text=trim(left(nresponse));
 output;
 end;
run;

data anno_lines;
length function $8 color $8 style $35;
when='b';
color='cx989ea1';
/* vertical lines */
xsys='1'; x=0; ysys='1'; y=0; function='move'; output;
xsys='1'; x=0; ysys='3'; y=2; function='draw'; output;
xsys='1'; x=25; ysys='1'; y=0; function='move'; output;
xsys='1'; x=25; ysys='3'; y=2; function='draw'; output;
xsys='1'; x=50; ysys='1'; y=0; function='move'; output;
xsys='1'; x=50; ysys='3'; y=2; function='draw'; output;
xsys='1'; x=75; ysys='1'; y=0; function='move'; output;
xsys='1'; x=75; ysys='3'; y=2; function='draw'; output;
xsys='1'; x=100; ysys='1'; y=0; function='move'; output;
xsys='1'; x=100; ysys='3'; y=2; function='draw'; output;
xsys='3'; x=3; ysys='3'; y=18; function='move'; output;
xsys='3'; x=3; ysys='3'; y=2; function='draw'; output;

/* horizontal lines */
xsys='3'; x=3; ysys='3'; y=18; function='move'; output;
xsys='1'; x=100; ysys='3'; y=18; function='draw'; output;
xsys='3'; x=3; ysys='3'; y=10; function='move'; output;
xsys='1'; x=100; ysys='3'; y=10; function='draw'; output;
xsys='3'; x=3; ysys='3'; y=2; function='move'; output;
xsys='1'; x=100; ysys='3'; y=2; function='draw'; output;

/* white-out some of the lines behind the 'Frozen' label */
xsys='1'; x=10; ysys='3'; y=18.1; function='move'; output;
xsys='1'; x=90; ysys='3'; y=27; function='box'; style='solid'; color='white'; output;

/* labels to left of table */
function='label'; position='6'; color=''; style='';
xsys='3'; x=10; ysys='3'; y=15; text='Total requested'; output;
xsys='3'; x=10; ysys='3'; y=7; text='Total remaining'; output;
style='marker'; text='U';
xsys='3'; x=5; ysys='3'; y=15-.5; color="cxc6514a"; output;
xsys='3'; x=5; ysys='3'; y=7-.5; color="cx4a82bd"; output;


run;

data anno_all; set anno_lines anno_values;
run;


pattern1 v=s c=cx4a82bd;
pattern2 v=s c=cxc6514a;

axis1 label=none order=(0 to 1 by 1) minor=none offset=(0,0);

axis2 label=('Frozen') order=('ILD' 'COPD' 'Control' 'Other');

title1 a=90 h=20 ' '; /* blank space to the left of the bar chart */
footnote1 height=15pct ' '; /* blank space for the annotated table */

proc gchart data=dx anno=anno_all;
vbar dx / type=sum sumvar=pctresponse
 subgroup=nmid nolegend
 raxis=axis1 maxis=axis2
 coutline=gray77;
run;

quit;
ODS HTML CLOSE;
ODS LISTING;

gchart.png

View solution in original post

3 REPLIES 3
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Move to the modern graphing system - sgplot/GTL.  Examples:

https://blogs.sas.com/content/?s=stacked

 

And you will find everything you ever wanted to know about graphs at:

https://blogs.sas.com/content/graphicallyspeaking/

lbarwick
Quartz | Level 8

Thanks. I think I found a solution. Here is some sample code I developed that is getting me to where I need to be (just need to add labels):

 


data dx;
input nmid $ pctmid $ dx $ nresponse pctresponse;
datalines;
totreq pctreq COPD 18 0.20
totrem pctrem COPD 8800 99.80
totreq pctreq Control 5 0.52
totrem pctrem Control 949 99.48
totreq pctreq ILD 0 0
totrem pctrem ILD 8124 100
totreq pctreq Other 200 12.93
totrem pctrem Other 1546 87.07
;
run; proc sort; by dx descending pctresponse; run;


ods graphics;                                                                                               

ods pdf file="X:\test1.pdf";
proc sgplot data=dx;
  title 'Frozen specimens requested';
  vbarparm category=dx response=pctresponse / group=pctmid dataskin=gloss;
  xaxistable nresponse / class=nmid label labelpos=left location=inside;
  xaxis display=(nolabel);
  keylegend / location=inside position=topright;
  yaxis offsetmax=0.1;
  run;
ods pdf close;
GraphGuy
Meteorite | Level 14

Here's one way to do it with gchart and annotate:

 

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

goptions device=png;
goptions border;
 
ODS LISTING CLOSE;
ODS HTML path=odsout body="&name..htm" style=htmlblue;

goptions gunit=pct htitle=6 ftitle="albany amt/bold" htext=4.25 ftext="albany amt";
gopitons ctext=gray33;

data dx;
input nmid $ pctmid $ dx $ nresponse pctresponse;
datalines;
totreq pctreq COPD 18 0.20
totrem pctrem COPD 8800 99.80
totreq pctreq Control 5 0.52
totrem pctrem Control 949 99.48
totreq pctreq ILD 0 0
totrem pctrem ILD 8124 100
totreq pctreq Other 200 12.93
totrem pctrem Other 1546 87.07
;
run;

data dx; set dx;
format pctresponse percentn7.0;
pctresponse=pctresponse/100;
run;

data anno_values; set dx;
xsys='2'; ysys='3'; hsys='3'; when='a';
function='label'; position='5'; 
xc=dx; 
if nmid='totreq' then do;
 y=15; 
 text=trim(left(nresponse));
 output;
 end;
if nmid='totrem' then do;
 y=7; 
 text=trim(left(nresponse));
 output;
 end;
run;

data anno_lines;
length function $8 color $8 style $35;
when='b';
color='cx989ea1';
/* vertical lines */
xsys='1'; x=0; ysys='1'; y=0; function='move'; output;
xsys='1'; x=0; ysys='3'; y=2; function='draw'; output;
xsys='1'; x=25; ysys='1'; y=0; function='move'; output;
xsys='1'; x=25; ysys='3'; y=2; function='draw'; output;
xsys='1'; x=50; ysys='1'; y=0; function='move'; output;
xsys='1'; x=50; ysys='3'; y=2; function='draw'; output;
xsys='1'; x=75; ysys='1'; y=0; function='move'; output;
xsys='1'; x=75; ysys='3'; y=2; function='draw'; output;
xsys='1'; x=100; ysys='1'; y=0; function='move'; output;
xsys='1'; x=100; ysys='3'; y=2; function='draw'; output;
xsys='3'; x=3; ysys='3'; y=18; function='move'; output;
xsys='3'; x=3; ysys='3'; y=2; function='draw'; output;

/* horizontal lines */
xsys='3'; x=3; ysys='3'; y=18; function='move'; output;
xsys='1'; x=100; ysys='3'; y=18; function='draw'; output;
xsys='3'; x=3; ysys='3'; y=10; function='move'; output;
xsys='1'; x=100; ysys='3'; y=10; function='draw'; output;
xsys='3'; x=3; ysys='3'; y=2; function='move'; output;
xsys='1'; x=100; ysys='3'; y=2; function='draw'; output;

/* white-out some of the lines behind the 'Frozen' label */
xsys='1'; x=10; ysys='3'; y=18.1; function='move'; output;
xsys='1'; x=90; ysys='3'; y=27; function='box'; style='solid'; color='white'; output;

/* labels to left of table */
function='label'; position='6'; color=''; style='';
xsys='3'; x=10; ysys='3'; y=15; text='Total requested'; output;
xsys='3'; x=10; ysys='3'; y=7; text='Total remaining'; output;
style='marker'; text='U';
xsys='3'; x=5; ysys='3'; y=15-.5; color="cxc6514a"; output;
xsys='3'; x=5; ysys='3'; y=7-.5; color="cx4a82bd"; output;


run;

data anno_all; set anno_lines anno_values;
run;


pattern1 v=s c=cx4a82bd;
pattern2 v=s c=cxc6514a;

axis1 label=none order=(0 to 1 by 1) minor=none offset=(0,0);

axis2 label=('Frozen') order=('ILD' 'COPD' 'Control' 'Other');

title1 a=90 h=20 ' '; /* blank space to the left of the bar chart */
footnote1 height=15pct ' '; /* blank space for the annotated table */

proc gchart data=dx anno=anno_all;
vbar dx / type=sum sumvar=pctresponse
 subgroup=nmid nolegend
 raxis=axis1 maxis=axis2
 coutline=gray77;
run;

quit;
ODS HTML CLOSE;
ODS LISTING;

gchart.png

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 3 replies
  • 1304 views
  • 1 like
  • 3 in conversation