Hi,
I used sgplot and sgpanel to create boxplots...is there any way I can assign unique color to each boxplot? I tried going through GTL...but I couldn't figure it out.
I could color individual boxplots using proc boxplot without ods graphics, but I'm not able to use panels then.
How can I use panels in proc boxplot or color boxplots in proc sgpanel/sgplot?
Thanks
As Dan and Snoopy have suggested, GTL and SG features were not fully fleshed out in SAS 9.2. SAS 9.3 is better. However, there is a way to get what you want with a little bit of work. Transform your data from a "Group" structure to a "Multi-Variable" structure. Then you can use the DISCRETEOFFSET option in GTL to get what you want. Note, you have to some extra work to know how many unique group values you want, and set up the details yourself.
Attached is a simple example, where I have transformed the mpg_city by Type and Origin data for SASHELP.CARS into TYPE and 3 columns for MPG, one each for USA, Asia and Europe. I did it the simple way using data step.
Then, you can overlay three BOXPLOT statements, each with the right amount of DISCRETEOFFSET and BOXWIDTH to get what you want. You have to use GTL as DISCRETEOFFSET was a late breaking option at 9.2 for just such use cases. There was no time to add it to SGPLOT. Colors come from style using CYCLEATTRS. To change group colors, change the style. See code and graph.
data trans;
set sashelp.cars(keep=origin type mpg_city where=(type ne 'Hybrid'));
drop mpg_city;
if Origin eq 'USA' then USA=mpg_city;
if Origin eq 'Asia' then Asia=mpg_city;
if Origin eq 'Europe' then Europe=mpg_city;
run;
proc template;
define statgraph BoxPlot;
begingraph;
entrytitle 'Mileage Distribution by Type and Origin';
layout overlay / cycleattrs=true
xaxisopts=(display=(ticks tickvalues))
yaxisopts=(label='Mileage');
boxplot x=type y=usa / discreteoffset=-0.25 boxwidth=0.2 name='a' legendlabel='USA';
boxplot x=type y=Asia / discreteoffset=0 boxwidth=0.2 name='b' legendlabel='Asia';
boxplot x=type y=Europe / discreteoffset= 0.25 boxwidth=0.2 name='c' legendlabel='Europe';
discretelegend 'a' 'b' 'c' / Title='Origin:';
endlayout;
endgraph;
end;
run;
ods listing;
proc sgrender data=trans template=BoxPlot;
run;
You want to change the color of each of the 4 boxes per panel, or of each panel to be consistent across the panel?
each of the 4 boxes per panel
ie. Assign a different color to each treatment group. similar to the graph attached(done by proc boxplot)
SGPANEL uses the data color list either from the template or from the DATACOLORS and DATACONTRASTCOLORS arguments in the SGPANEL. So for example:
ods html style=htmlblue path="c:\temp" gpath="c:\temp" file="mypanel.html";
proc sgpanel data=sashelp.prdsale;
panelby country;
styleattrs datacolors=(red green blue orange) datacontrastcolors=(green red orange blue);
vbox actual/group=prodtype;
run;
ods html close;
produces red and green boxes with green and red bars.
Or you can modify the colors in the style template. By default they will have different colors so I'm not sure why yours don't - that must be an element of your style template, whichever you are using (either by default or by design).
vbox/hbox does not have 'group=' option. instead it has 'category=' option.
When I use group =option for other graphs (scatter, bar) the colors are assigned differently by default. However, for boxplot I'm unable to use group=option.
Is 'styleattrs' to be used as a statement or option? either way I'm getting syntax error
Thanks
You must have SAS 9.2. Group support for box plots was added in SAS 9.3. Unfortunately, there is not a solution in SAS 9.2.
Hmm, I'm using 9.4, so it's possible this is 9.4 code that won't work on whatever version you're on. The above code works on 9.4. On 9.3, styleattrs does not work, but group does (so the default htmlblue style gives red,blue,green,etc. colors). You could still modify the graph colors in PROC TEMPLATE for whichever style you were using.
If you're in 9.2, group doesn't work indeed; 9.2 was pretty early in the SG-procedures' lives and they didn't have a lot of the useful options they do today. Perhaps one of the SAS folk will have a better answer for you in that case.
Either way I would recommend posting your version number in future questions about SGprocs (well, anything, but in particular SGprocs) as the version makes a huge difference in what they are capable of.
As Dan and Snoopy have suggested, GTL and SG features were not fully fleshed out in SAS 9.2. SAS 9.3 is better. However, there is a way to get what you want with a little bit of work. Transform your data from a "Group" structure to a "Multi-Variable" structure. Then you can use the DISCRETEOFFSET option in GTL to get what you want. Note, you have to some extra work to know how many unique group values you want, and set up the details yourself.
Attached is a simple example, where I have transformed the mpg_city by Type and Origin data for SASHELP.CARS into TYPE and 3 columns for MPG, one each for USA, Asia and Europe. I did it the simple way using data step.
Then, you can overlay three BOXPLOT statements, each with the right amount of DISCRETEOFFSET and BOXWIDTH to get what you want. You have to use GTL as DISCRETEOFFSET was a late breaking option at 9.2 for just such use cases. There was no time to add it to SGPLOT. Colors come from style using CYCLEATTRS. To change group colors, change the style. See code and graph.
data trans;
set sashelp.cars(keep=origin type mpg_city where=(type ne 'Hybrid'));
drop mpg_city;
if Origin eq 'USA' then USA=mpg_city;
if Origin eq 'Asia' then Asia=mpg_city;
if Origin eq 'Europe' then Europe=mpg_city;
run;
proc template;
define statgraph BoxPlot;
begingraph;
entrytitle 'Mileage Distribution by Type and Origin';
layout overlay / cycleattrs=true
xaxisopts=(display=(ticks tickvalues))
yaxisopts=(label='Mileage');
boxplot x=type y=usa / discreteoffset=-0.25 boxwidth=0.2 name='a' legendlabel='USA';
boxplot x=type y=Asia / discreteoffset=0 boxwidth=0.2 name='b' legendlabel='Asia';
boxplot x=type y=Europe / discreteoffset= 0.25 boxwidth=0.2 name='c' legendlabel='Europe';
discretelegend 'a' 'b' 'c' / Title='Origin:';
endlayout;
endgraph;
end;
run;
ods listing;
proc sgrender data=trans template=BoxPlot;
run;
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 25. Read more here about why you should contribute and what is in it for you!
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.