Hi everyone.
I noticed that when I do several SGPANELS with styleattrs datacolors specified and GROUP option the color of the groups gets flipped from one SGPANEL to another. Here is my code:
Data test1;
input channel $ product $ available $ month count;
cards;
CH1 PROD1 YES 1 1
CH1 PROD1 NO 2 1
CH2 PROD2 NO 1 2
CH2 PROD1 NO 3 5
CH2 PROD3 YES 1 2
CH3 PROD1 YES 1 5
CH3 PROD2 NO 2 2
CH3 PROD3 YES 4 1
;
run;
ODS HTML;
proc sgpanel data= test1;
where channel = 'CH1';
styleattrs datacolors=(cx5e2750 cx5bbbb7);
panelby PRODUCT/ novarname columns=3 rows = 1 spacing=10 border uniscale=all;
vbar MONTH / response=count DATALABEL=count group=available GROUPDISPLAY=CLUSTER DATALABELFITPOLICY=NONE DATASKIN = GLOSS DATALABELattrs = (COLOR = CX4D4D4D) NOOUTLINE fillattrs= (TRANSPARENCY= .6);
rowaxis display=(nolabel noline noticks) grid offsetmin=0 offsetmax=0 valueattrs=(color=gray33);
run;
proc sgpanel data= test1;
where channel = 'CH2';
styleattrs datacolors=(cx5e2750 cx5bbbb7);
panelby PRODUCT/ novarname columns=3 rows = 1 spacing=10 border uniscale=all;
vbar MONTH / response=count DATALABEL=count group=available GROUPDISPLAY=CLUSTER DATALABELFITPOLICY=NONE DATASKIN = GLOSS DATALABELattrs = (COLOR = CX4D4D4D) NOOUTLINE fillattrs= (TRANSPARENCY= .6);
rowaxis display=(nolabel noline noticks) grid offsetmin=0 offsetmax=0 valueattrs=(color=gray33);
run;
proc sgpanel data= test1;
where channel = 'CH3';
styleattrs datacolors=(cx5e2750 cx5bbbb7);
panelby PRODUCT/ novarname columns=3 rows = 1 spacing=10 border uniscale=all;
vbar MONTH / response=count DATALABEL=count group=available GROUPDISPLAY=CLUSTER DATALABELFITPOLICY=NONE DATASKIN = GLOSS DATALABELattrs = (COLOR = CX4D4D4D) NOOUTLINE fillattrs= (TRANSPARENCY= .6);
rowaxis display=(nolabel noline noticks) grid offsetmin=0 offsetmax=0 valueattrs=(color=gray33);
run;
And here is what I'm getting:
On the first panel, NO is purple and YES is olive. On the second one, it is the other way around.
Why is that and how to keep colors consistent?
Hi @Jack_Loktiev,
As @Reeza mentioned, you should use attribute maps to get consistent colours. The reason why it is switching is because for some channels and products the value of "NO" is first and for other channels and products the value of "YES" is first. Below shows an example (with help from the SAS help guide) of how you can incorporate attribute maps by using the discrete attribute map dataset along with the dattrmap=myattrmap and attrid=myid options. As you can see you do not need to use the styleattrs option now.
Data test1;
input channel $ product $ available $ month count;
cards;
CH1 PROD1 YES 1 1
CH1 PROD1 NO 2 1
CH2 PROD2 NO 1 2
CH2 PROD1 NO 3 5
CH2 PROD3 YES 1 2
CH3 PROD1 YES 1 5
CH3 PROD2 NO 2 2
CH3 PROD3 YES 4 1
;
run;
data myattrmap;
length fillcolor $ 9;
input ID $ value $ fillcolor $;
datalines;
myid YES cx5bbbb7
myid NO cx5e2750
;
run;
ODS HTML;
proc sgpanel data= test1 dattrmap=myattrmap;
where channel = 'CH1';
panelby PRODUCT/ novarname columns=3 rows = 1 spacing=10 border uniscale=all;
vbar MONTH / response=count DATALABEL=count group=available attrid=myid GROUPDISPLAY=CLUSTER DATALABELFITPOLICY=NONE DATASKIN = GLOSS DATALABELattrs = (COLOR = CX4D4D4D) NOOUTLINE fillattrs= (TRANSPARENCY= .6);
rowaxis display=(nolabel noline noticks) grid offsetmin=0 offsetmax=0 valueattrs=(color=gray33);
run;
proc sgpanel data= test1 dattrmap=myattrmap;
where channel = 'CH2';
panelby PRODUCT/ novarname columns=3 rows = 1 spacing=10 border uniscale=all;
vbar MONTH / response=count DATALABEL=count group=available attrid=myid GROUPDISPLAY=CLUSTER DATALABELFITPOLICY=NONE DATASKIN = GLOSS DATALABELattrs = (COLOR = CX4D4D4D) NOOUTLINE fillattrs= (TRANSPARENCY= .6);
rowaxis display=(nolabel noline noticks) grid offsetmin=0 offsetmax=0 valueattrs=(color=gray33);
run;
proc sgpanel data= test1 dattrmap=myattrmap;
where channel = 'CH3';
panelby PRODUCT/ novarname columns=3 rows = 1 spacing=10 border uniscale=all;
vbar MONTH / response=count DATALABEL=count group=available attrid=myid GROUPDISPLAY=CLUSTER DATALABELFITPOLICY=NONE DATASKIN = GLOSS DATALABELattrs = (COLOR = CX4D4D4D) NOOUTLINE fillattrs= (TRANSPARENCY= .6);
rowaxis display=(nolabel noline noticks) grid offsetmin=0 offsetmax=0 valueattrs=(color=gray33);
run;
Hi @Jack_Loktiev,
As @Reeza mentioned, you should use attribute maps to get consistent colours. The reason why it is switching is because for some channels and products the value of "NO" is first and for other channels and products the value of "YES" is first. Below shows an example (with help from the SAS help guide) of how you can incorporate attribute maps by using the discrete attribute map dataset along with the dattrmap=myattrmap and attrid=myid options. As you can see you do not need to use the styleattrs option now.
Data test1;
input channel $ product $ available $ month count;
cards;
CH1 PROD1 YES 1 1
CH1 PROD1 NO 2 1
CH2 PROD2 NO 1 2
CH2 PROD1 NO 3 5
CH2 PROD3 YES 1 2
CH3 PROD1 YES 1 5
CH3 PROD2 NO 2 2
CH3 PROD3 YES 4 1
;
run;
data myattrmap;
length fillcolor $ 9;
input ID $ value $ fillcolor $;
datalines;
myid YES cx5bbbb7
myid NO cx5e2750
;
run;
ODS HTML;
proc sgpanel data= test1 dattrmap=myattrmap;
where channel = 'CH1';
panelby PRODUCT/ novarname columns=3 rows = 1 spacing=10 border uniscale=all;
vbar MONTH / response=count DATALABEL=count group=available attrid=myid GROUPDISPLAY=CLUSTER DATALABELFITPOLICY=NONE DATASKIN = GLOSS DATALABELattrs = (COLOR = CX4D4D4D) NOOUTLINE fillattrs= (TRANSPARENCY= .6);
rowaxis display=(nolabel noline noticks) grid offsetmin=0 offsetmax=0 valueattrs=(color=gray33);
run;
proc sgpanel data= test1 dattrmap=myattrmap;
where channel = 'CH2';
panelby PRODUCT/ novarname columns=3 rows = 1 spacing=10 border uniscale=all;
vbar MONTH / response=count DATALABEL=count group=available attrid=myid GROUPDISPLAY=CLUSTER DATALABELFITPOLICY=NONE DATASKIN = GLOSS DATALABELattrs = (COLOR = CX4D4D4D) NOOUTLINE fillattrs= (TRANSPARENCY= .6);
rowaxis display=(nolabel noline noticks) grid offsetmin=0 offsetmax=0 valueattrs=(color=gray33);
run;
proc sgpanel data= test1 dattrmap=myattrmap;
where channel = 'CH3';
panelby PRODUCT/ novarname columns=3 rows = 1 spacing=10 border uniscale=all;
vbar MONTH / response=count DATALABEL=count group=available attrid=myid GROUPDISPLAY=CLUSTER DATALABELFITPOLICY=NONE DATASKIN = GLOSS DATALABELattrs = (COLOR = CX4D4D4D) NOOUTLINE fillattrs= (TRANSPARENCY= .6);
rowaxis display=(nolabel noline noticks) grid offsetmin=0 offsetmax=0 valueattrs=(color=gray33);
run;
Thanks for the explanation and example, @djrisks . But I'm still getting the same result even though I copied your code (I mean I didn't miss anything from your code for sure)
You're welcome @Jack_Loktiev. When I run the code, I get the greenish colour for YES and the reddish colour for NO. Do you see any warnings in the log when you run the code? Perhaps it could be your SAS version. Are you definitely looking at the latest 3 plots?
I noticed in the legend in the second plot, the NO value is before the YES value. But, the colours are still consistent.
I think you already get the solution by Reeza an djrisks.
Or padding these missing month and yes_no.
Data test1;
input channel $ product $ available $ month count;
cards;
CH1 PROD1 YES 1 1
CH1 PROD1 NO 2 1
CH2 PROD2 NO 1 2
CH2 PROD1 NO 3 5
CH2 PROD3 YES 1 2
CH3 PROD1 YES 1 5
CH3 PROD2 NO 2 2
CH3 PROD3 YES 4 1
;
run;
proc sql;
create table test2 as
select *
from (select * from
(select distinct channel from test1),
(select distinct product from test1),
(select distinct available from test1),
(select distinct month from test1)) as a
natural left join test1 as b;
quit;
proc sgpanel data= test2;
where channel = 'CH1';
styleattrs datacolors=(cx5e2750 cx5bbbb7);
panelby PRODUCT/ novarname columns=3 rows = 1 spacing=10 border uniscale=all;
vbar MONTH /
response=count DATALABEL=count group=available GROUPDISPLAY=CLUSTER DATALABELFITPOLICY=NONE DATASKIN = GLOSS DATALABELattrs = (COLOR = CX4D4D4D) NOOUTLINE fillattrs= (TRANSPARENCY= .6);
rowaxis display=(nolabel noline noticks) grid offsetmin=0 offsetmax=0 valueattrs=(color=gray33);
run;
proc sgpanel data= test2;
where channel = 'CH2';
styleattrs datacolors=(cx5e2750 cx5bbbb7);
panelby PRODUCT/ novarname columns=3 rows = 1 spacing=10 border uniscale=all;
vbar MONTH /
response=count DATALABEL=count group=available GROUPDISPLAY=CLUSTER DATALABELFITPOLICY=NONE DATASKIN = GLOSS DATALABELattrs = (COLOR = CX4D4D4D) NOOUTLINE fillattrs= (TRANSPARENCY= .6);
rowaxis display=(nolabel noline noticks) grid offsetmin=0 offsetmax=0 valueattrs=(color=gray33) ;
run;
proc sgpanel data= test2;
where channel = 'CH3';
styleattrs datacolors=(cx5e2750 cx5bbbb7);
panelby PRODUCT/ novarname columns=3 rows = 1 spacing=10 border uniscale=all;
vbar MONTH /
response=count DATALABEL=count group=available GROUPDISPLAY=CLUSTER DATALABELFITPOLICY=NONE DATASKIN = GLOSS DATALABELattrs = (COLOR = CX4D4D4D) NOOUTLINE fillattrs= (TRANSPARENCY= .6);
rowaxis display=(nolabel noline noticks) grid offsetmin=0 offsetmax=0 valueattrs=(color=gray33);
run;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.