Hi all,
I need a hand in producing a bar chart that is Manhattan-like. X-axis is one of the variables in my dataset and Y-axis should be generated automatically with a suitable low/high limits where these limits would be again taken from the values of the variables represented by the bar chart.
I tried to attach an Excel sheet that shows exactly what I mean (3 series of data [3 variables PCT_222, PCT_233, PCT_244) all together in the same plot and their X-axis is a variable called (Class) while their Y-axis is generated automatically using their values all together), but I was unable to due to the fact that the third shows .xlsx as invalid extension. Therefore, I attached a PDF that is generated by the Excel sheet.
I'm not sure if this is direct in SAS or not and I hope so.I searched before writing here but could not find any useful resource which shows somthing similar to my requirement and a straight answer to it. Therefore, I hope the Graph/ODS experts here can assit in resolving this problem which might turned to be a trivial one.
Regards
You should have a look at ODS Graphics. @Jay54 maintains a blog with lots of great examples.
To get you started find below some sample code. I have not tested it with SAS 9.3, you have a go.
data have;
infile cards dlm=",";
input
Class
Overall pct_overall : percent10.
V_222 PCT_222 : percent10.
V_233 PCT_233 : percent10.
V_244 PCT_244: percent10.
;
format pct_: percent10.2;
cards;
4,3,1%,0,0%,0,0%,3,2%
5,22,15%,60,45%,31,15%,40,30%
7,50,35%,58,38%,44,33%,33,40%
8,130,27%,77,32%,50,40%,20,15%
9,70,18%,18,13%,15,11%,18,9%
10,33,8%,13,8%,17,8%,9,7%
13,9,4%,6,4%,25,20%,7,4%
14,11,2%,2,1%,7,3%,1,1%
16,18,6%,0,0%,9,8%,4,5%
17,12,3%,0,0%,4,2%,5,5%
19,8,2%,0,0%,6,3%,1,1%
20,6,1%,0,0%,3,1%,2,3%
;
proc sgplot data=have;
vbar class / response=pct_overall barwidth=0.2 discreteoffset=-0.3
legendlabel="Overall" fillattrs=(color=cxffff00)
;
vbar class / response=pct_222 barwidth=0.2 discreteoffset=-0.1
legendlabel="V_222 "
;
vbar class / response=pct_233 barwidth=0.2 discreteoffset=0.1
legendlabel="V_233"
;
vbar class / response=pct_244 barwidth=0.2 discreteoffset=0.3
legendlabel="V_244"
;
keylegend / noborder across=1 location=inside position=right;
yaxis label="Account(%)";
run;
proc transpose
data=have
out=have_trsp
;
by Class;
var pct_:;
run;
proc sgplot data=have_trsp;
vbar class /
response=col1 group=_name_ groupdisplay=cluster GROUPORDER=DATA
;
yaxis label="Account(%)";
keylegend /
across=1 noborder location=inside position=right title=""
;
run;
Bruno
You should have a look at ODS Graphics. @Jay54 maintains a blog with lots of great examples.
To get you started find below some sample code. I have not tested it with SAS 9.3, you have a go.
data have;
infile cards dlm=",";
input
Class
Overall pct_overall : percent10.
V_222 PCT_222 : percent10.
V_233 PCT_233 : percent10.
V_244 PCT_244: percent10.
;
format pct_: percent10.2;
cards;
4,3,1%,0,0%,0,0%,3,2%
5,22,15%,60,45%,31,15%,40,30%
7,50,35%,58,38%,44,33%,33,40%
8,130,27%,77,32%,50,40%,20,15%
9,70,18%,18,13%,15,11%,18,9%
10,33,8%,13,8%,17,8%,9,7%
13,9,4%,6,4%,25,20%,7,4%
14,11,2%,2,1%,7,3%,1,1%
16,18,6%,0,0%,9,8%,4,5%
17,12,3%,0,0%,4,2%,5,5%
19,8,2%,0,0%,6,3%,1,1%
20,6,1%,0,0%,3,1%,2,3%
;
proc sgplot data=have;
vbar class / response=pct_overall barwidth=0.2 discreteoffset=-0.3
legendlabel="Overall" fillattrs=(color=cxffff00)
;
vbar class / response=pct_222 barwidth=0.2 discreteoffset=-0.1
legendlabel="V_222 "
;
vbar class / response=pct_233 barwidth=0.2 discreteoffset=0.1
legendlabel="V_233"
;
vbar class / response=pct_244 barwidth=0.2 discreteoffset=0.3
legendlabel="V_244"
;
keylegend / noborder across=1 location=inside position=right;
yaxis label="Account(%)";
run;
proc transpose
data=have
out=have_trsp
;
by Class;
var pct_:;
run;
proc sgplot data=have_trsp;
vbar class /
response=col1 group=_name_ groupdisplay=cluster GROUPORDER=DATA
;
yaxis label="Account(%)";
keylegend /
across=1 noborder location=inside position=right title=""
;
run;
Bruno
Hi Bruno,
Thanks for your time and I really appreciate your professional answer as a complete solution including recreating the data and perform all necessary steps to reach to proc sgplot. In addition, doing the sgplot using two approaches (though I liked the transposed data as it shortened the code even with the extra step of proc transpose).
Thanks a lot that is exactly what I want.
Last small question, Can I control the vbar colors for each group?
Regards
Have a look here, with SAS 9.4 it is very easy, with SAS 9.3, there is some more effort
Bruno
Hi. Not sure what you mean by a Manhattan plot since your exaple does not look like what I understand such a plot to be.
If you want a standard Manhattan plot, take a look at ...
Creating Manhattan Plots with SAS/Graph
http://www.sascommunity.org/wiki/Creating_Manhattan_Plots_with_SAS/Graph
First paragraph in this link ...
A Manhattan plot is a type of bar chart that is sometimes used in the visualization of genome-wide association data. Some examples can be found by using Google to search for "Manhattan plots" then clicking on "Images" on the upper left-hand side of the search results. You can see Manhattan plots used in publications by clicking on either of the following links: example 1 or example 2.
has couple links to Manhattan plots in publications.
Hi. Here's an example using GPLOT (admittedly more stuff than SGPLOT). It produced the attached chart (default color scheme used) ...
* your data;
data x;
input class overall pct_over v_222 pct_222 v_233 pct_233 v_244 pct_244;
datalines;
4 3 1 0 0 0 0 3 2
5 22 15 60 45 31 15 40 30
7 50 35 58 38 44 33 33 40
8 130 27 77 32 50 40 20 15
9 70 18 18 13 15 11 18 9
10 33 8 13 8 17 8 9 7
13 9 4 6 4 25 20 7 4
14 11 2 2 1 7 3 1 1
16 18 6 0 0 9 8 4 5
17 12 3 0 0 4 2 5 5
19 8 2 0 0 6 3 1 1
20 6 1 0 0 3 1 2 3
;
* rearrange your data for use in PROC GCHART;
* three variables in new data set;
* CLASS;
* _NAME_ (the name of the PCT variable from data set x);
* COL1 (values of percentages in data set x);
proc transpose data=x out=y;
by class;
var pct: ;
run;
* rescale the percentages from 0-100 to 0-1 (so you can use the PERCENT format in GCHART);
data y;
set y;
col1 = col1/100;
run;
* specify a destination for the PNG file produced by GCHART;
filename gout 'z:\chart.png';
* specify details for the chart;
goptions reset=all gunit=pct ftext='calibri' htext=2 gsfname=gout
dev=png xpixels=1500 ypixels=1000;
* override the default axis look in GCHART;
axis1 label=none value=none;
axis2 label=none offset=(2,2)pct;
axis3 label=(h=3 a=90 'ACCOUNT(%)') order=0 to .50 by .05 minor=none;
* move the legend inside the chart frame and tweak defaults;
legend1 position=(top inside right) across=1 label=none shape=bar(3,4)
value=('V_222' 'V_233' 'V_244' 'OVERALL') mode=protect offset=(-5,-5)pct;
* adds whitespace at top;
title1 ls=2;
* adds a centered label for the horizontal access;
footnote1 h=3 j=c 'CLASS';
* draw the chart (produces a PNG file);
proc gchart data=y;
vbar _name_ / subgroup=_name_ sumvar=col1 group=class
maxis=axis1 gaxis=axis2 raxis=axis3
space=0 legend=legend1;
format col1 percent.;
run;
quit;
Hi MikeZdeb,
I'd like to thank you too for the professional answer you provided. This has also an added value as you've used different proc (proc gchart) which did a similar result but with a slightly different way.
Thanks a lot MikeZdeb. I'd also consider this as a full answer to my query.
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
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.