Hello,
Using SAS 9.4, I have the attached dataset. I would like to create a mirror bar chart with the x and y axes as labelled in the datalines and the each side of the mirror being the group variable. Does anyone know any efficient code to make this happen? Thank you
data have;
input yaxis $ xaxis group $;
datalines;
High 346 AHS
Middle-High 220 AHS
Middle-Low 268 AHS
Low 312 AHS
High 281 ASP
Middle-High 276 ASP
Middle-Low 278 ASP
Low 248 ASP
;
run;
Like this:
data have;
input group $ yaxis $ xaxis x2 x3;
x2DL=abs(x2);
x3DL=abs(x3);
datalines;
AHS High 346 346 .
AHS Middle-High 220 220 .
AHS Middle-Low 268 268 .
AHS Low 312 312 .
ASP High -281 . -281
ASP Middle-High -276 . -276
ASP Middle-Low -278 . -278
ASP Low -248 . -248
;
run;
ODS graphics / width=1200px height=800px;
proc sgplot data=have;
styleattrs datacolors=(teal black);
hbarparm category=yaxis response=xaxis / group=group nooutline name='x' dataskin=matte;
scatter x=x2 y=yaxis /DATALABEL=x2DL DATALABELATTRS=(color=white size=12) DATALABELPOS=LEFT markerattrs=(size=0);
scatter x=x3 y=yaxis /DATALABEL=x3DL DATALABELATTRS=(color=white size=12) DATALABELPOS=RIGHT markerattrs=(size=0);
xaxis values=(-360 -340 -320 -300 -380 -260 -240 -220 -200 -180 -160 -140 -120 -100 -80 -60 -40 -20
0 20 40 60 80 100 120 140 160 180 200 220 240 260 280 300 320 340 360)
VALUESDISPLAY=("360" "340" "320" "300" "380" "260" "240" "220" "200" "180" "160" "140" "120" "100" "80" "60" "40" "20"
"0" "20" "40" "60" "80" "100" "120" "140" "160" "180" "200" "220" "240" "260" "280" "300" "320" "340" "360")
FITPOLICY=STAGGER
label= 'Quartile Ranking';
yaxis label= 'Frequency';
label group= 'Source';
title 'Figure 1. Total Correct Per Quartile of Ranking';
run;
Bart
See @Ksharp code in this post
https://communities.sas.com/t5/SAS-Programming/Proc-GCHART-display-variable-in-the-bar/m-p/914690
@GS2 wrote:
Hello,
Using SAS 9.4, I have the attached dataset. I would like to create a mirror bar chart with the x and y axes as labelled in the datalines and the each side of the mirror being the group variable. Does anyone know any efficient code to make this happen? Thank you
data have; input yaxis $ xaxis group $; datalines; High 346 AHS Middle-High 220 AHS Middle-Low 268 AHS Low 312 AHS High 281 ASP Middle-High 276 ASP Middle-Low 278 ASP Low 248 ASP ; run;
Thank you for the direction that was quite helpful. I updated my dataset to accommodate the example code, see attached. I am still having a few issues based on my code.
1. On the x axis the numbers are negative, is there a way to make both sides of the axis positive?
2. The labels on the bars show at the extreme ends so that not all of the number is showing, is there a way to center the labels on the bar?
3. Is there a way to adjust the tick values? I would prefer the value to be in increments of 20. I tried using values=() and listing the values but that has not worked.
Thank you
data have;
input group $ yaxis $ xaxis x2 x3;
datalines;
AHS High 346 346 .
AHS Middle-High 220 220 .
AHS Middle-Low 268 268 .
AHS Low 312 312 .
ASP High -281 . -281
ASP Middle-High -276 . -276
ASP Middle-Low -278 . -278
ASP Low -248 . -248
;
run;
proc sgplot data=have;
styleattrs datacolors=(teal black);
hbarparm category=yaxis response=xaxis / group=group nooutline name='x' dataskin=matte;
scatter x=x2 y=yaxis /markerchar=x2 labelstrip markercharattrs=(color=white size=12);
scatter x=x3 y=yaxis /markerchar=x3 labelstrip markercharattrs=(color=white size=12);
xaxis values=(-360 -340 -320 -300 -380 -260 -240 -220 -200 -180 -160 -140 -120 -100 -80 -60 -40 -20 0 20 40 60 80 100 120 140 160 180 200 220 240 260 280 300 320 340 360)
label= 'Quartile Ranking';
yaxis label= 'Frequency';
label group= 'Source';
title 'Figure 1. Total Correct Per Quartile of Ranking';
run;
Like this:
data have;
input group $ yaxis $ xaxis x2 x3;
x2DL=abs(x2);
x3DL=abs(x3);
datalines;
AHS High 346 346 .
AHS Middle-High 220 220 .
AHS Middle-Low 268 268 .
AHS Low 312 312 .
ASP High -281 . -281
ASP Middle-High -276 . -276
ASP Middle-Low -278 . -278
ASP Low -248 . -248
;
run;
ODS graphics / width=1200px height=800px;
proc sgplot data=have;
styleattrs datacolors=(teal black);
hbarparm category=yaxis response=xaxis / group=group nooutline name='x' dataskin=matte;
scatter x=x2 y=yaxis /DATALABEL=x2DL DATALABELATTRS=(color=white size=12) DATALABELPOS=LEFT markerattrs=(size=0);
scatter x=x3 y=yaxis /DATALABEL=x3DL DATALABELATTRS=(color=white size=12) DATALABELPOS=RIGHT markerattrs=(size=0);
xaxis values=(-360 -340 -320 -300 -380 -260 -240 -220 -200 -180 -160 -140 -120 -100 -80 -60 -40 -20
0 20 40 60 80 100 120 140 160 180 200 220 240 260 280 300 320 340 360)
VALUESDISPLAY=("360" "340" "320" "300" "380" "260" "240" "220" "200" "180" "160" "140" "120" "100" "80" "60" "40" "20"
"0" "20" "40" "60" "80" "100" "120" "140" "160" "180" "200" "220" "240" "260" "280" "300" "320" "340" "360")
FITPOLICY=STAGGER
label= 'Quartile Ranking';
yaxis label= 'Frequency';
label group= 'Source';
title 'Figure 1. Total Correct Per Quartile of Ranking';
run;
Bart
A bit more practical version:
ODS graphics / width=1200px height=800px;
%macro plotMe(st,ed,by);
proc sgplot data=have;
styleattrs datacolors=(teal black);
hbarparm category=yaxis response=xaxis / group=group nooutline name='x' dataskin=matte;
scatter x=x2 y=yaxis /DATALABEL=x2DL DATALABELATTRS=(color=white size=12) DATALABELPOS=LEFT markerattrs=(size=0);
scatter x=x3 y=yaxis /DATALABEL=x3DL DATALABELATTRS=(color=white size=12) DATALABELPOS=RIGHT markerattrs=(size=0);
xaxis values=(
%do i=&st. %to &ed. %by &by.;
&i.
%end;
)
VALUESDISPLAY=(
%do i=&st. %to &ed. %by &by.;
"%sysfunc(ABS(&i.))"
%end;
)
FITPOLICY=STAGGER
label= 'Quartile Ranking';
yaxis label= 'Frequency';
label group= 'Source';
title 'Figure 1. Total Correct Per Quartile of Ranking';
run;
%mend plotMe;
%plotMe(-360,360,20);
For anyone looking at this thread, I believe that the "mirror bar" graph is more commonly called a butterfly plot or sometimes a tornado chart. For information about creating a butterfly plot in SAS, see
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
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.
Ready to level-up your skills? Choose your own adventure.