Hi folks,
I have an issue with the GROUP= options in SGPLOT.
So basically I'm doing line plot for some lab tests - plotting median, minimum, maximum - using 3 plot (series) statement. I have 2 treatment group (A, B). Some tests have been done for both treatment, some are done only for either of them. Now for those tests which are done for both treatments, the graph looks fine (first graph in the attachment). But for those which are done for either treatment the data colors are not getting assigned correctly. In 2nd graph in attachment, treatment A should get black as in the x-axis table beneath the plot.
Instead the median line is getting blue but the minimum and maximum are getting black. Attached is my code.
%do i=1 %to &tests.;
proc sgplot data= lb4(where=(param="&&par&i")) noautolegend noborder;
styleattrs datacolors=(black blue) datacontrastcolors=(black blue);
series x=avisit1 y=max1 / group=trt grouporder=reversedata lineattrs=(thickness=2 pattern=shortdash) nomissinggroup;
series x=avisit1 y=median1 / group=trt grouporder=reversedata lineattrs=(thickness=2 pattern=solid) name='c' nomissinggroup;
series x=avisit1 y=min1 / group=trt grouporder=reversedata lineattrs=(thickness=2 pattern=shortdash) nomissinggroup;
yaxis type=log logbase=10 /*logstyle=logexponent*/ logvtype=expanded max=1000 label="&&unit&i";
xaxis type=linear values=(0 to 6 by 1) label='Months since infusion';
xaxistable count / class=trt labelattrs=(size=8) colorgroup=trt pad=(top=1cm) location=outside valueattrs=(size=8)
label="Number of(*ESC*){unicode '000a'x}patients:";
keylegend 'c' / location=inside position=bottomright ;
run;
ods startpage=yes;
%end;
Does anyone know why this is happening? Is there anything wrong in the GROUP= option or STYLEATTRS statement?
Any help is appreciated.
I'm using SAS9.4 (M5) in Windows 64 bit.
Thanks
The best way to guarantee attribute assignment is through an attributes map.This should work for you:
data attrmap;
retain id "trtid";
length linecolor $ 5;
input value $ linecolor $;
cards;
A blue
B black
;
run;
%do i=1 %to &tests.;
proc sgplot data= lb4(where=(param="&&par&i")) noautolegend noborder dattrmap=attrmap;
series x=avisit1 y=max1 / group=trt grouporder=reversedata lineattrs=(thickness=2 pattern=shortdash) nomissinggroup attrid=trtid;
series x=avisit1 y=median1 / group=trt grouporder=reversedata lineattrs=(thickness=2 pattern=solid) name='c' nomissinggroup attrid=trtid;
series x=avisit1 y=min1 / group=trt grouporder=reversedata lineattrs=(thickness=2 pattern=shortdash) nomissinggroup attrid=trtid;
yaxis type=log logbase=10 /*logstyle=logexponent*/ logvtype=expanded max=1000 label="&&unit&i";
xaxis type=linear values=(0 to 6 by 1) label='Months since infusion';
xaxistable count / class=trt labelattrs=(size=8) colorgroup=trt pad=(top=1cm) location=outside valueattrs=(size=8)
label="Number of(*ESC*){unicode '000a'x}patients:";
keylegend 'c' / location=inside position=bottomright ;
run;
ods startpage=yes;
%end;
I believe StyleAttrs rotates the styles, but if a value is missing the next value would get the colour so then the colours are out of whack. Is that what you're seeing?
If that's the case then try using an attribute map instead.
https://blogs.sas.com/content/graphicallyspeaking/?s=Discrete+attribute+map
Typically, when you want explicit control over the mapping between groups and attributes, use a discrete attribute map.
The best way to guarantee attribute assignment is through an attributes map.This should work for you:
data attrmap;
retain id "trtid";
length linecolor $ 5;
input value $ linecolor $;
cards;
A blue
B black
;
run;
%do i=1 %to &tests.;
proc sgplot data= lb4(where=(param="&&par&i")) noautolegend noborder dattrmap=attrmap;
series x=avisit1 y=max1 / group=trt grouporder=reversedata lineattrs=(thickness=2 pattern=shortdash) nomissinggroup attrid=trtid;
series x=avisit1 y=median1 / group=trt grouporder=reversedata lineattrs=(thickness=2 pattern=solid) name='c' nomissinggroup attrid=trtid;
series x=avisit1 y=min1 / group=trt grouporder=reversedata lineattrs=(thickness=2 pattern=shortdash) nomissinggroup attrid=trtid;
yaxis type=log logbase=10 /*logstyle=logexponent*/ logvtype=expanded max=1000 label="&&unit&i";
xaxis type=linear values=(0 to 6 by 1) label='Months since infusion';
xaxistable count / class=trt labelattrs=(size=8) colorgroup=trt pad=(top=1cm) location=outside valueattrs=(size=8)
label="Number of(*ESC*){unicode '000a'x}patients:";
keylegend 'c' / location=inside position=bottomright ;
run;
ods startpage=yes;
%end;
Thanks DanH_sas.
I had never used attribute map but it seems a good solution. My question now, does attribute map overrides a style element that I have defined through proc template? I have defined style element at project level and now when I tried to use attribute map as you explained, it seems the style element is taking priority over attribute map.
Do you know how to overcome this?
Many thanks.
Btw, I can have a workaround in my code to overcome this problem. Just curious to know if that is possible through data attribute map.
Many thanks.
Any attributes that are needed by the plot are first pulled from the attributes map. If the needed attribute is not defined in the map, it is pulled from the style. In your example, I defined only the colors, because you have the line pattern and thickness defined as attributes in each plot. In general, the attributes from the attribute map win over the style attributes. Take a look at my paper from last year for a more in-depth discussion of how these pieces interact.
http://support.sas.com/resources/papers/proceedings17/SAS0675-2017.pdf
Hope this helps!
Dan
Thanks Dan. I just found out why style elements defined in proc template were taking precedence over discrete attribute map earlier. It was my mistake. That is corrected now.
I've used ATTRID= options in XAXISTABLE statement in the same PROC SGPLOT. But it is not taking effect there. I believe its a valid option. Is anything wrong there?
proc sgplot data=lb4 (where=(param="&&par&i")) noautolegend noborder dattrmap=attrmap;
series x=avisit1 y=max1 / group=trt01p lineattrs=(thickness=2 pattern=shortdash) attrid=trtid nomissinggroup;
series x=avisit1 y=median1 / group=trt01p lineattrs=(thickness=2 pattern=solid) name='c' attrid=trtid nomissinggroup;
series x=avisit1 y=min1 / group=trt01p lineattrs=(thickness=2 pattern=shortdash) attrid=trtid nomissinggroup;
yaxis type=log logbase=10 /*logstyle=logexponent*/ logvtype=expanded max=1000 label="&&unit&i";
xaxis type=linear values=(0 to 6 by 1) label='Months since infusion';
xaxistable count / class=trt01p labelattrs=(size=8) pad=(top=1cm) location=outside valueattrs=(size=8)
label="Number of(*ESC*){unicode '000a'x}patients:" attrid=trtid nomissingclass;
keylegend 'c' / location=inside position=bottomright ;
run;
Thanks everyone for the helpful guidance.
On the XAXISTABLE, also add COLORGROUP=trt01p. The CLASS breaks up the table based on classification, but does not affect the visual attributes. COLORGROUP will give you the color change you want.
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!
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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: