BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
grsanford
Fluorite | Level 6

Hello, 

I have used sganno as a means to add letters of significance above figures for a long time. It works but it is exceedingly cumbersome adjusting x/y coordinates if there are many letters/bars/boxes. The letters are never equidistant or perfectly centered above whiskers and the second you change any formatting you have to begin monkeying around with x/y coordinates again. There MUST be a streamlined or more efficient way to do this. Below is code for the attached graph illustrating my point. 

 

data anno; 
length function $8. label $200.;
 
function="text"; label="Change in SOC, 1989 to 2019 (Mg ha(*ESC*){sup '-1'} yr(*ESC*){sup '-1'})";
rotate = 90; X1 = 1.5; Y1 = 50; width = 1000; TEXTSIZE = 8;
output;
 
function="text"; label="C"; *add letter denoting statistical grouping;
    rotate = 0; 
X1 = 27.025; Y1 = 63; ANCHOR = "center";
width = 30; TEXTSIZE = 10; TEXTSTYLE="normal";
output;
 
function="text"; label="C"; *add letter denoting statistical grouping;
    rotate = 0; 
X1 = 36.575; Y1 = 65; ANCHOR = "center";
width = 30; TEXTSIZE = 10; TEXTSTYLE="normal";
output;
 
function="text"; label="C"; *add letter denoting statistical grouping;
    rotate = 0; 
X1 = 46.125; Y1 = 65; ANCHOR = "center";
width = 30; TEXTSIZE = 10; TEXTSTYLE="normal";
output;
 
function="text"; label="B"; *add letter denoting statistical grouping;
    rotate = 0; 
X1 = 55.675; Y1 = 68; ANCHOR = "center";
width = 30; TEXTSIZE = 10; TEXTSTYLE="normal";
output;
 
function="text"; label="B"; *add letter denoting statistical grouping;
    rotate = 0; 
X1 = 65.225; Y1 = 71.5; ANCHOR = "center";
width = 30; TEXTSIZE = 10; TEXTSTYLE="normal";
output;
 
function="text"; label="A"; *add letter denoting statistical grouping;
    rotate = 0; 
X1 = 74.775; Y1 = 84; ANCHOR = "center";
width = 30; TEXTSIZE = 10; TEXTSTYLE="normal";
output;
 
function="text"; label="A"; *add letter denoting statistical grouping;
    rotate = 0; 
X1 = 84.325; Y1 = 93; ANCHOR = "center";
width = 30; TEXTSIZE = 10; TEXTSTYLE="normal";
output;
 
function="text"; label="C"; *add letter denoting statistical grouping;
    rotate = 0; 
X1 = 27.025; Y1 = 18.5; ANCHOR = "center";
width = 30; TEXTSIZE = 10; TEXTSTYLE="normal";
output;
 
function="text"; label="BC"; *add letter denoting statistical grouping;
    rotate = 0; 
X1 = 36.575; Y1 = 20.5; ANCHOR = "center";
width = 30; TEXTSIZE = 10; TEXTSTYLE="normal";
output;
 
function="text"; label="C"; *add letter denoting statistical grouping;
    rotate = 0; 
X1 = 46.125; Y1 = 16.5; ANCHOR = "center";
width = 30; TEXTSIZE = 10; TEXTSTYLE="normal";
output;
 
function="text"; label="B"; *add letter denoting statistical grouping;
    rotate = 0; 
X1 = 55.675; Y1 = 22; ANCHOR = "center";
width = 30; TEXTSIZE = 10; TEXTSTYLE="normal";
output;
 
function="text"; label="B"; *add letter denoting statistical grouping;
    rotate = 0; 
X1 = 65.225; Y1 = 24; ANCHOR = "center";
width = 30; TEXTSIZE = 10; TEXTSTYLE="normal";
output;
 
function="text"; label="A"; *add letter denoting statistical grouping;
    rotate = 0; 
X1 = 74.775; Y1 = 36; ANCHOR = "center";
width = 30; TEXTSIZE = 10; TEXTSTYLE="normal";
output;
 
function="text"; label="A"; *add letter denoting statistical grouping;
    rotate = 0; 
X1 = 84.325; Y1 = 44; ANCHOR = "center";
width = 30; TEXTSIZE = 10; TEXTSTYLE="normal";
output;
run;
 
ods graphics on / noborder;
 
proc sgpanel data=fig1 noautolegend sganno=anno;
panelby dpt / rows=2 columns=1 novarname uniscale=column;
   vbox _value_ / group=sys nomean lineattrs=(color=black) medianattrs=(color=black) whiskerattrs=(color=black) capshape=none;
   refline 0 / lineattrs=(color=crimson);
   rowaxis label=" " offsetmax=.1;
   keylegend / title=" " position=bottom noborder;
   format dpt dpt.;
   format sys sys.;
run;
 
 
Example Figure.jpg

 

1 ACCEPTED SOLUTION

Accepted Solutions
Ksharp
Super User
data have;
 set sashelp.heart;
 keep sex bp_status weight;
run;


ods select none;
ods output   SGPanel=box ;
proc sgpanel data=have noautolegend ;
panelby sex / rows=2 columns=1 novarname uniscale=column;
vbox weight/category=BP_Status nooutliers;
run;
ods select all;

proc sort data=box;by Sex BOX_WEIGHT_X_BP_STATUS____X; run;
proc transpose data=box(where=(BOX_WEIGHT_X_BP_STATUS___ST in ('MIN' 'Q1' 'MEDIAN' 'Q3' 'MAX' ))) out=want;
by Sex BOX_WEIGHT_X_BP_STATUS____X; 
var BOX_WEIGHT_X_BP_STATUS____Y;
id BOX_WEIGHT_X_BP_STATUS___ST;
run;
data want;
 set want;
 label=choosec(mod(_n_,4)+1,'A', 'B', 'BC', 'C');
run;

proc sgpanel data=want noautolegend ;
panelby sex / rows=2 columns=1 novarname uniscale=column;
highlow x=BOX_WEIGHT_X_BP_STATUS____X low=Q1 high=Q3/group=BOX_WEIGHT_X_BP_STATUS____X type=bar barwidth=0.4 lineattrs=(color=black);
scatter x=BOX_WEIGHT_X_BP_STATUS____X y=max/datalabel=label labelstrip datalabelpos=top datalabelattrs=(size=10) markerattrs=(size=0);
highlow x=BOX_WEIGHT_X_BP_STATUS____X low=median high=median/group=BOX_WEIGHT_X_BP_STATUS____X type=bar barwidth=0.4 lineattrs=(color=black) nofill;
highlow x=BOX_WEIGHT_X_BP_STATUS____X low=q3 high=max/group=BOX_WEIGHT_X_BP_STATUS____X lineattrs=(color=black);
highlow x=BOX_WEIGHT_X_BP_STATUS____X low=min high=q1/group=BOX_WEIGHT_X_BP_STATUS____X lineattrs=(color=black);

colaxis type=discrete;
rowaxis label=" " offsetmax=.1;
refline 150 / lineattrs=(color=crimson);
run;



Ksharp_0-1721699061848.png

 

View solution in original post

3 REPLIES 3
Jay54
Meteorite | Level 14

The TEXT statement in SGPLOT / SGPANEL  or TEXTPLOT in GTL may be the right solution for you to place text inside the graph.  You could also see if the HIGHLABEL option of HIGHLOW plot can be useful for this.

Ksharp
Super User
data have;
 set sashelp.heart;
 keep sex bp_status weight;
run;


ods select none;
ods output   SGPanel=box ;
proc sgpanel data=have noautolegend ;
panelby sex / rows=2 columns=1 novarname uniscale=column;
vbox weight/category=BP_Status nooutliers;
run;
ods select all;

proc sort data=box;by Sex BOX_WEIGHT_X_BP_STATUS____X; run;
proc transpose data=box(where=(BOX_WEIGHT_X_BP_STATUS___ST in ('MIN' 'Q1' 'MEDIAN' 'Q3' 'MAX' ))) out=want;
by Sex BOX_WEIGHT_X_BP_STATUS____X; 
var BOX_WEIGHT_X_BP_STATUS____Y;
id BOX_WEIGHT_X_BP_STATUS___ST;
run;
data want;
 set want;
 label=choosec(mod(_n_,4)+1,'A', 'B', 'BC', 'C');
run;

proc sgpanel data=want noautolegend ;
panelby sex / rows=2 columns=1 novarname uniscale=column;
highlow x=BOX_WEIGHT_X_BP_STATUS____X low=Q1 high=Q3/group=BOX_WEIGHT_X_BP_STATUS____X type=bar barwidth=0.4 lineattrs=(color=black);
scatter x=BOX_WEIGHT_X_BP_STATUS____X y=max/datalabel=label labelstrip datalabelpos=top datalabelattrs=(size=10) markerattrs=(size=0);
highlow x=BOX_WEIGHT_X_BP_STATUS____X low=median high=median/group=BOX_WEIGHT_X_BP_STATUS____X type=bar barwidth=0.4 lineattrs=(color=black) nofill;
highlow x=BOX_WEIGHT_X_BP_STATUS____X low=q3 high=max/group=BOX_WEIGHT_X_BP_STATUS____X lineattrs=(color=black);
highlow x=BOX_WEIGHT_X_BP_STATUS____X low=min high=q1/group=BOX_WEIGHT_X_BP_STATUS____X lineattrs=(color=black);

colaxis type=discrete;
rowaxis label=" " offsetmax=.1;
refline 150 / lineattrs=(color=crimson);
run;



Ksharp_0-1721699061848.png

 

grsanford
Fluorite | Level 6

So brilliant and simple. Thank you!

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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
  • 326 views
  • 4 likes
  • 3 in conversation