BookmarkSubscribeRSS Feed
LzyButEfficient
Calcite | Level 5

Hi I want to connect the vertices of the segments for a Grotta bar charts.   I'm using annotate to manually connect the vertices of the segments.  The problem is that the graph space doesn't perfectly align to the data percentages, so it's a bit of a guessing game/trial by errors on what the vertices coordinates are on the graph.  I'm wondering if SAS has a way to automate from the data without manually using annotate.  Thanks.  

Output and code:

mrs shift.PNG


proc format;
value mrs
0="mRS 0"
1="mRS 1"
2="mRS 2"
3="mRS 3"
4="mRS 4"
5="mRS 5"
6="mRS 6";
run ;


data mrs;
input group $ mrs percent;
format mrs Mrs. percent percentn10.1;
datalines;
C 0 .177
C 1 .167
C 2 .115
C 3 .146
C 4 .115
C 5 .01
C 6 .271
T 0 .163
T 1 .128
T 2 .163
T 3 .174
T 4 .093
T 5 .058
T 6 .221
;
run;

/* Create Line Segment to connect the bars */
data lineseg;
x1=0.2; x2=0.2; y1=61.8; y2=38.3;function= 'line'; drawspace ='wallpercent' ;linecolor ='blue';output;
x1=17.8; x2=16.4; y1=61.8; y2=38.3;function= 'line'; drawspace ='wallpercent' ;linecolor ='blue';output;
x1=34.4; x2=29.1; y1=61.8; y2=38.3;function= 'line'; drawspace ='wallpercent' ;linecolor ='blue';output;
x1=45.9; x2=45.4; y1=61.8; y2=38.3;function= 'line'; drawspace ='wallpercent' ;linecolor ='blue';output;
x1=60.4; x2=62.7; y1=61.8; y2=38.3;function= 'line'; drawspace ='wallpercent' ;linecolor ='blue';output;
x1=71.8; x2=71.9; y1=61.8; y2=38.3;function= 'line'; drawspace ='wallpercent' ;linecolor ='blue';output;
x1=72.8; x2=77.7; y1=61.8; y2=38.3;function= 'line'; drawspace ='wallpercent' ;linecolor ='blue';output;
x1=99.8; x2=99.6; y1=61.8; y2=38.3;function= 'line'; drawspace ='wallpercent' ;linecolor ='blue';output;

run;

ods graphics / border=off;
/* Plot the graph */
proc sgplot data=mrs sganno=lineseg;
hbar group/ group=mrs response=percent seglabel seglabelfitpolicy=noclip
barwidth=.5 NOSTATLABEL seglabelattrs=(weight=bold size=8pt);
yaxis label=" " ;
xaxis label=" " values=(0 to 1 by .1);
title "Distribution of 90day mRS";
keylegend /title= " " ;
run;

 

2 REPLIES 2
GraphGuy
Meteorite | Level 14

Perhaps there's an easy way to do it with ods graphics(?) ... but nothing comes to mind.

 

The difficulty with annotating the blue lines is that annotate does not know where the side (width) edges of the bar segments are ... unless you use annotate to draw the bar segments.

 

Therefore I wrote some data-driven SAS/Graph annotate code  (rather than hard-coded annotate) that might give you some ideas. (of course you'd also have to annotate the legend & labels)

 

proc format;
value mrs
0="mRS 0"
1="mRS 1"
2="mRS 2"
3="mRS 3"
4="mRS 4"
5="mRS 5"
6="mRS 6";
run ;

data mrs;
input group $ mrs percent;
format mrs Mrs. percent percentn10.1;
datalines;
C 0 .177
C 1 .167
C 2 .115
C 3 .146
C 4 .115
C 5 .01
C 6 .271
T 0 .163
T 1 .128
T 2 .163
T 3 .174
T 4 .093
T 5 .058
T 6 .221
;
run;

data mrs; set mrs;
if group='T' then y_center=33.3;
if group='C' then y_center=66.6;
if mrs=0 then cumulative_pct=0;
cumulative_pct+percent;
run;

proc sort data=mrs out=mrs_sorted;
by mrs group;
run;

proc sql;
create table anno_text as
select unique group as text, y_center as y
from mrs;
quit; run;
data anno_text; set anno_text;
xsys='1'; ysys='2'; hsys='3'; when='a';
function='label'; position='<'; size=4; color='gray33';
x=-1;
run;

%let width=15;  /* width of bars */

/* annotate colored polygons for the bar segments */
data anno_mrs_colors; set mrs_sorted;
length function $8 color $12;
xsys='2'; ysys='2'; hsys='3'; when='a';
style='solid';
if mrs=0 then color='dodgerblue';
if mrs=1 then color='pink';
if mrs=2 then color='purple';
if mrs=3 then color='orange';
if mrs=4 then color='burlywood';
if mrs=5 then color='gray77';
if mrs=6 then color='red';
x=cumulative_pct;
y=y_center-&width/2;
function='poly'; output;  /* bottom right corner */
x=cumulative_pct-percent;
function='polycont'; output;   /* bottom left corner */
y=y_center+&width/2;
function='polycont'; output;   /* top left corner */
x=cumulative_pct;
function='polycont'; output;   /* top right corner */
run;

/* draw outlines around the colored polygons, and draw connecting line between C & T */
data anno_mrs_outlines; set mrs_sorted;
length function $8 color $12;
xsys='2'; ysys='2'; hsys='3'; when='a';
/* if you've already drawn group='C' box and you're starting on the group='T' box ... */
if group='T' then do;
 size=.1; color='blue';
 function='draw';
 x=cumulative_pct;
 y=y_center+&width/2;
 output;
 end;
size=.1; color='gray55';
x=cumulative_pct;
y=y_center-&width/2;
function='move'; output;  /* bottom right corner */
x=cumulative_pct-percent;
function='draw'; output;   /* bottom left corner */
y=y_center+&width/2;
function='draw'; output;   /* top left corner */
x=cumulative_pct;
function='draw'; output;   /* top right corner */
y=y_center-&width/2;
function='draw'; output;   /* bottom right corner */
run;

/* combine your annotate datasets */
data anno_mrs; set anno_mrs_colors anno_mrs_outlines anno_text;
run;

axis1 order=(0 to 100 by 100) minor=none label=none offset=(0,0) value=(color=white);
axis2 order=(0 to 1.10 by .10) minor=none label=none offset=(0,0);

symbol1 value=none interpol=none; /* invisible plot markers */

title1 h=16pt font='albany amt' "Distribution of 90day mRS";

proc gplot data=mrs anno=anno_mrs;
format cumulative_pct percent7.0;
plot y_center*cumulative_pct=1 /
 vaxis=axis1 haxis=axis2;

 

grotta.png 

Ksharp
Super User
proc format;
value mrs
0="mRS 0"
1="mRS 1"
2="mRS 2"
3="mRS 3"
4="mRS 4"
5="mRS 5"
6="mRS 6";
run ;


data mrs;
input group $ mrs percent;
format mrs Mrs. percent percentn10.1;
datalines;
C 0 .177
C 1 .167
C 2 .115
C 3 .146
C 4 .115
C 5 .01
C 6 .271
T 0 .163
T 1 .128
T 2 .163
T 3 .174
T 4 .093
T 5 .058
T 6 .221
;
run;

data temp;
 merge mrs(keep=group mrs percent rename=(percent=percent1) where=(group='C'))
       mrs(keep=group mrs percent rename=(percent=percent2) where=(group='T'))
;
by mrs;
cum_PCT_ROW1+percent1;
cum_PCT_ROW2+percent2;
run;

filename sganno temp;
data _null_;
 set temp end=last;
 file sganno;
 put  '%SGLINE( X1=' cum_PCT_ROW1 ',Y1=75, X2=' cum_PCT_ROW2 ',Y2=25,X1SPACE="DATAVALUE",X2SPACE="DATAVALUE",Y1SPACE="DATAPERCENT",Y2SPACE="DATAPERCENT",LINECOLOR="grey",LINEPATTERN="SOLID")';
run;


%sganno
data sganno;
%include sganno;
run;

ods graphics/width=5in height=3in noscale;
proc sgplot data=mrs noborder  sganno=sganno  ;
styleattrs datacolors=(CXEDF8E9 CXC7E9C0 CXA1D99B CX74C476 CX41AB5D CX238B45 CX005A32 );
hbarparm category=group response=percent/ group=mrs nooutline seglabel 
SEGLABELFITPOLICY=none seglabelattrs=(size=8) barwidth=0.5  ;
yaxis label=' ' splitchar='|' fitpolicy=splitalways splitjustify=right offsetmin=0.15 offsetmax=0.15;
xaxis offsetmin=0 offsetmax=0.01 valueshint label=' ';
keylegend /position=top down=1 title='' noborder autooutline;
run;

Ksharp_0-1686051527774.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
  • 2 replies
  • 507 views
  • 2 likes
  • 3 in conversation