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

Hello all,

Thanks again for the great code on creating a butterfly chart. Here's the basic code I'm using but now I'd like to enhance it to include both the value in parentheses below the percentage. (see picture).

 

Thanks for your great help!

Enhanced Butterfly chart.jpgproc format;
	picture posval low-<0='00000%'
	(prefix='-')
	 0='9%'
	 0<-high='00000%';
run;

data have;
call streaminit(123);
do date='01jan2022'd  to '20jan2022'd;
 value=rand('integer',-100,100);
 group=ifc(value>0,'pos_diff','neg_diff');
 output;
end;
format date date9.  value posval.;
run;



proc sgplot data=have;
hbarparm category=date response=value/group=group datalabel=value
 GROUPDISPLAY=CLUSTER  DATALABELFITPOLICY=INSIDEPREFERRED
;
keylegend /title='';
yaxis label='';
xaxis label='';
run;
1 ACCEPTED SOLUTION

Accepted Solutions
Ksharp
Super User
/*
Try TEXT statement
*/
proc format;
 picture posval low-<0='00000%'
 (prefix='-')
  0='9%'
  0<-high='00000%';
run;

data have;
call streaminit(123);
do date='01jan2022'd  to '20jan2022'd;
 value=rand('integer',-100,100);
 n=rand('integer',100,1000);
 group=ifc(value>0,'pos_diff','neg_diff');
 if value>0 then datalabel_pos=cats(value,"%|(",n,")");
  else datalabel_neg=cats(value,"%|(",n,")");
 output;
 call missing(datalabel_pos,datalabel_neg);
end;
format date date9.  value posval.;
run;



proc sgplot data=have;
hbarparm category=date response=value/group=group name='x' ;
text x=value y=date text=datalabel_pos/splitchar='|'   strip contributeoffsets=none 
SPLITCHAR='|'  SPLITJUSTIFY=left SPLITPOLICY=splitalways position=right ;
text x=value y=date text=datalabel_neg/splitchar='|'   strip contributeoffsets=none 
SPLITCHAR='|'  SPLITJUSTIFY=left SPLITPOLICY=splitalways position=left ;
keylegend 'x'/title='';
yaxis label=' ';
xaxis label=' ' offsetmin=0.1 offsetmax=0.1;
run;

Ksharp_0-1676374895239.png

 

View solution in original post

5 REPLIES 5
ballardw
Super User

Vertical stacking of multiple text items means that you will have to consider some things such as the width of your bars and the font size of the text. Otherwise you are going to have visual alignment issues. Also how many variables are involved? If you try to use a data label with value and have the additional text in a different variable you will have some fun getting the things not to overlap or collide.

 

How critical is having the text immediately at the end of the bars? Yaxis tables on the edge of the display area might be more flexible in the long run.

 

Is the other text, the apparent count, going to be in a separate variable? or will have both the percentage and count in a single variable (which can no longer be used as a Response variable, okay for Group but not response).

Reeza
Super User

Side by side is easier by far.

 

data have;
call streaminit(123);
do date='01jan2022'd  to '20jan2022'd;
 value=rand('integer',-100,100);
 value_num = value*1000;
 location = value-1;
 group=ifc(value>0,'pos_diff','neg_diff');
 text_display = catx(", ", value_num, value);
 output;
end;
format date date9.  value posval.;
run;



proc sgplot data=have;
hbarparm category=date response=value/group=group 
 GROUPDISPLAY=CLUSTER  
;
text x=location y=date text=text_display;
keylegend /title='';
yaxis label='';
xaxis label='';
run;
Ksharp
Super User
/*
Try TEXT statement
*/
proc format;
 picture posval low-<0='00000%'
 (prefix='-')
  0='9%'
  0<-high='00000%';
run;

data have;
call streaminit(123);
do date='01jan2022'd  to '20jan2022'd;
 value=rand('integer',-100,100);
 n=rand('integer',100,1000);
 group=ifc(value>0,'pos_diff','neg_diff');
 if value>0 then datalabel_pos=cats(value,"%|(",n,")");
  else datalabel_neg=cats(value,"%|(",n,")");
 output;
 call missing(datalabel_pos,datalabel_neg);
end;
format date date9.  value posval.;
run;



proc sgplot data=have;
hbarparm category=date response=value/group=group name='x' ;
text x=value y=date text=datalabel_pos/splitchar='|'   strip contributeoffsets=none 
SPLITCHAR='|'  SPLITJUSTIFY=left SPLITPOLICY=splitalways position=right ;
text x=value y=date text=datalabel_neg/splitchar='|'   strip contributeoffsets=none 
SPLITCHAR='|'  SPLITJUSTIFY=left SPLITPOLICY=splitalways position=left ;
keylegend 'x'/title='';
yaxis label=' ';
xaxis label=' ' offsetmin=0.1 offsetmax=0.1;
run;

Ksharp_0-1676374895239.png

 

Reeza
Super User
Nice solution!
SASGeek
Obsidian | Level 7
Thank you so much!

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 5 replies
  • 1142 views
  • 11 likes
  • 4 in conversation