I am trying to create a graph using the PROC TEMPLATE. I am using this code since most of the code written previously. But I am trying to control the colors of the data. I have two different GROUPS, I was able to control markers, patterns but not the color It giving in blue and red. because of default ATTRPRIORITY=COLOR rotation pattern .I read the SAS®9.4 Graph Template Language User’s Guide "https://citeseerx.ist.psu.edu/viewdoc/download doi=10.1.1.354.127&rep=rep1&type=pdf#page=80&zoom=100,0,161"
But I really could not find how I can achieve my requirement.
ods path(prepend) work.templat(update);
proc template;
define statgraph series;
begingraph / BORDER=False /*datacolors=(green blue)*/ datasymbols=( circle Asterisk ) datalinepatterns= (1 4);
layout overlay / xaxisopts=( label=('X axis label') tickvalueattrs=(family='Courier New' size=8 weight=bold) labelattrs=(family='Courier New' size=8 weight=bold)
linearopts=( viewmin=-5.0 viewmax=20.0 TICKVALUELIST=(0 1 4 8 10 12 14 16) TICKVALUEFITPOLICY=ROTATE ))/*tickvaluesequence=( start=0.0 end=60.0 )*/
yaxisopts=( label=('Yaxis label') labelattrs=(family='Courier New' size=8 weight=bold) tickvalueattrs=(family='Courier New' size=8 )
linearopts=( viewmin=-15.0 viewmax=5.0 tickvaluesequence=( start=-15.0 end=6.0 increment=5.0)));
seriesplot x=avisitn y=Estimate / group=grp name='series' display=(markers)
connectorder=xaxis;
scatterplot x=avisitn y=Estimate / yerrorupper = upper yerrorlower = lower group=grp
name='scatter' ;*markerattrs=(symbol= asterisk);
discretelegend 'series' / title='Treatment' opaque=false border=true halign=left valign=bottom
displayclipped=true across=1 order=rowmajor location=inside
titleattrs=(family='Courier New' size=8 color= red);
Layout Gridded/
rows=3 order=columnmajor border=false autoalign=(bottomright);
entry textattrs=(size=8pt) halign=left
"*xxxx";
entry textattrs=(size=8pt) halign=left
"xxx";
entry textattrs=(size=8pt) halign=left
"*** xxx";
endlayout;
endlayout;
endgraph;
end;
run;
I am also looking to add the data at the bottom of the x axis that represent the Y axis values .
I was able to control colors and adding the data with PROC SGPLOT. Thank you for your time and inputs.
Try this:
proc template;
define statgraph series;
begingraph / BORDER=False ATTRPRIORITY=NONE datacontrastcolors=(orange purple) datasymbols=( circle Asterisk ) datalinepatterns= (1 4);* datacolors=(green blue) ;
layout lattice / rows = 2 rowgutter=10 columngutter=10 rowWEIGHTS = preferred;
layout overlay / xaxisopts=( label=('X axis label') tickvalueattrs=(family='Courier New' size=8 weight=bold) labelattrs=(family='Courier New' size=8 weight=bold) linearopts=( viewmin=0.0 viewmax=28.0 TICKVALUELIST=(0 1 2 4 8 10 12 16 20 24 28) TICKVALUEFITPOLICY=ROTATE )) yaxisopts=( label=('Yaxis label') labelattrs=(family='Courier New' size=8 weight=bold) tickvalueattrs=(family='Courier New' size=8 ) linearopts=( viewmin=-15.0 viewmax=5.0 tickvaluesequence=( start=-15.0 end=6.0 increment=5.0)));
seriesplot x=week y=Estimate / group=drug name='series' display=(markers) connectorder=xaxis;
scatterplot x=week y=Estimate / yerrorupper = upper yerrorlower = lower group=drug name='scatter' ;
discretelegend 'series' / title='Treatment' opaque=false border=true halign=left valign=bottom displayclipped=true across=1 order=rowmajor location=inside titleattrs=(family='Courier New' size=8 color= red);
endlayout;
Layout Overlay / walldisplay=none xaxisopts=(display=none);
AxisTable VALUE=N X=week/ class=drug labelPosition=min Display=(Label);
endlayout;
endlayout;
endgraph;
end;
run;
ods html;
ods graphics on/ width=9 in height=4.4 in ;
proc sgrender data=have template=series;
*format avisitn wkfmt.;
run;
ods _all_ close;
Without data and the Sgrender statements it is next to impossible to test GTL code. With options that interact with ODS STYLE setttings, such as Attrpriority the style used becomes important also.
Did you try adding ATTRPRIORITY=NONE to the BeginGraph statement?
The basic tool for providing a table near the axis as requested is, believe it or not, an AXISTABLE statement.
Which would have the basic form similar to this.
AXISTABLE x=<x axis variable name> value=<y axis variable name> ;
Again, without data, I am not sure if you need other options on the Axistable.
My apologies. I tried the ATTRPRIORITY=NONE option at bigingraph and ods graphic statement but it didn't worked for me. I am attaching the data.( Ref: https://blogs.sas.com/content/graphicallyspeaking/files/2012/07/AnnoRisk_SAS93_Code1.txt ) My second question in the previous version is add the 'N" variable values at the bottom of the table. Is creating the Annotation dataset is the option?
ods html close;
%let gpath='C:\';
%let dpi=200;
ods listing style=htmlblue image_dpi=&dpi gpath=&gpath;
data have;
input Week Drug $ estimate lower upper N;
if week ne 28 then estimate2=estimate;
if week eq 2 then do; ylabel='C'; label='Number of subjects at visit'; end;
datalines;
0 A 0 0 0 216
0 B 0 0 0 431
1 A -0.1 -2.0 1.8 210
1 B 0.5 -1.0 2.1 423
2 A -0.6 -2.8 1.8 206
2 B -3.2 -4.8 -1.6 364
4 A 0.4 -1.9 2.4 199
4 B -1.8 -3.6 0.0 362
8 A -1.6 -4.0 0.8 191
8 B -2.8 -4.4 -1.2 337
12 A -3.0 -5.6 -0.4 184
12 B -2.0 -3.6 -0.4 315
16 A -1.2 -3.6 1.2 176
16 B -3.0 -5.0 -1.0 311
20 A -1.6 -4.6 1.4 169
20 B -3.2 -4.8 -1.6 299
24 A -2.2 -5.0 0.6 164
24 B -2.0 -3.8 -0.2 293
28 A -1.6 -3.6 1.0 214
28 B -1.8 -3.2 -0.4 429
;
run;
ods path(prepend) work.templat(update);
proc template;
define statgraph series;
begingraph / BORDER=False
ATTRPRIORITY=NONE datasymbols=( circle Asterisk ) datalinepatterns= (1 4);* datacolors=(green blue) ;
layout overlay / xaxisopts=( label=('X axis label') tickvalueattrs=(family='Courier New' size=8 weight=bold) labelattrs=(family='Courier New' size=8 weight=bold)
linearopts=( viewmin=-5.0 viewmax=24.0 TICKVALUELIST=(0 1 2 4 8 10 12 16 20 24) TICKVALUEFITPOLICY=ROTATE ))/*tickvaluesequence=( start=0.0 end=60.0 )*/
yaxisopts=( label=('Yaxis label') labelattrs=(family='Courier New' size=8 weight=bold) tickvalueattrs=(family='Courier New' size=8 )
linearopts=( viewmin=-15.0 viewmax=5.0 tickvaluesequence=( start=-15.0 end=6.0 increment=5.0)));
seriesplot x=week y=Estimate / group=drug name='series' display=(markers)
connectorder=xaxis;
scatterplot x=week y=Estimate / yerrorupper = upper yerrorlower = lower group=drug
name='scatter' ;*markerattrs=(symbol= asterisk);
discretelegend 'series' / title='Treatment' opaque=false border=true halign=left valign=bottom
displayclipped=true across=1 order=rowmajor location=inside
titleattrs=(family='Courier New' size=8 color= red);
endlayout;
endgraph;
end;
run;
ods html;
ods graphics on/ width=9 in height=4.4 in ;
proc sgrender data=have template=series;
*format avisitn wkfmt.;
run;
ods _all_ close;
To control line and marker colors, you need to use the DATACONTRASTCOLORS option instead of the DATACOLORS option.
As @ballardw said, you will want to use an AXISTABLE to display that data. However, if you want that data displayed BELOW the axis, you'll need to wrap your plot in a LAYOUT LATTICE. The general structure will look something like the following:
begingraph;
layout lattice / columnweights=preferred rowweights=preferred columndatarange=union columns=1 columnweights=preferred rowweights=preferred;
layout overlay;
<your plot>
endlayout;
Layout Overlay / walldisplay=none xaxisopts=(display=none);
AxisTable VALUE=<tablevar1> X=<xvar> / labelPosition=min Display=(Label);
endlayout;
Layout Overlay / walldisplay=none xaxisopts=(display=none);
AxisTable VALUE=<tablevar2> X=<xvar> / labelPosition=min Display=(Label);
endlayout;
endlayout;
endgraph;
Hope this helps!
Dan
Thanks @DanH_sas , The color control worked. I am still having the trouble to get the data info outside the axis. thanks again for your time. If you get a chance can you please any resources that I can look into to achieved the data under x axis.
It seems you really have a one-cell graph. It may be much easier to use the SGPLOT procedure with the XAXISTABLE statement to create your graph. The XAXISTABLE statement allows you to place the table above or below the x-axis. LOCATION=Outside is the default.
If GTL is a must, you can run SGPLOT as in the example with a TMPLOUT= option to obtain the GTL necessary to create the graph.
See this as a general example:
Thank you @Jay54 for your valuable suggestion. The reason for me to use 'GTL' because most of the code existed and have the certain nuisances written in the code for a decent output. Only there is a need of placing the data under the X axis. Yes I do tried the SGPLOT ( of course , I used some of your work from the Book , SAS publications and Some from suggestions from here.) If I could not achieve this With 'GTL' I will movie to SGPLOT. I kept that as last option to save the time. Thank you for your input.
@SASuserlot , What do you see when you try the structure I gave you? Can you post your template?
Yes. Like you mentioned it was displaying data inside the graph. I came across this solution which works for me for time being. But I definitely work more on this to use the latest updated procedures. I used boxplot statement by having two rows in Lattice lay out. I am not sure this is efficient way to achieve. I am providing my code. Please provide your inputs.
ods html close;
%let gpath='C:\';
%let dpi=200;
ods listing style=htmlblue image_dpi=&dpi gpath=&gpath;
data have;
input Week Drug $ estimate lower upper N;
if week ne 28 then estimate2=estimate;
if week eq 2 then do; ylabel='C'; label='Number of subjects at visit'; end;
datalines;
0 A 0 0 0 216
0 B 0 0 0 431
1 A -0.1 -2.0 1.8 210
1 B 0.5 -1.0 2.1 423
2 A -0.6 -2.8 1.8 206
2 B -3.2 -4.8 -1.6 364
4 A 0.4 -1.9 2.4 199
4 B -1.8 -3.6 0.0 362
8 A -1.6 -4.0 0.8 191
8 B -2.8 -4.4 -1.2 337
12 A -3.0 -5.6 -0.4 184
12 B -2.0 -3.6 -0.4 315
16 A -1.2 -3.6 1.2 176
16 B -3.0 -5.0 -1.0 311
20 A -1.6 -4.6 1.4 169
20 B -3.2 -4.8 -1.6 299
24 A -2.2 -5.0 0.6 164
24 B -2.0 -3.8 -0.2 293
28 A -1.6 -3.6 1.0 214
28 B -1.8 -3.2 -0.4 429
;
run;
ods path(prepend) work.templat(update);
proc template;
define statgraph series;
begingraph / BORDER=False
ATTRPRIORITY=NONE datacontrastcolors=(orange purple) datasymbols=( circle Asterisk ) datalinepatterns= (1 4);* datacolors=(green blue) ;
layout lattice / rows = 2 rowgutter=10 columngutter=10 rowWEIGHTS = (0.90 0.1);
cell;
cellheader;
endcellheader;
layout overlay / xaxisopts=( label=('X axis label') tickvalueattrs=(family='Courier New' size=8 weight=bold) labelattrs=(family='Courier New' size=8 weight=bold)
linearopts=( viewmin=0.0 viewmax=28.0 TICKVALUELIST=(0 1 2 4 8 10 12 16 20 24 28) TICKVALUEFITPOLICY=ROTATE ))/*tickvaluesequence=( start=0.0 end=60.0 )*/
yaxisopts=( label=('Yaxis label') labelattrs=(family='Courier New' size=8 weight=bold) tickvalueattrs=(family='Courier New' size=8 )
linearopts=( viewmin=-15.0 viewmax=5.0 tickvaluesequence=( start=-15.0 end=6.0 increment=5.0)));
seriesplot x=week y=Estimate / group=drug name='series' display=(markers)
connectorder=xaxis;
scatterplot x=week y=Estimate / yerrorupper = upper yerrorlower = lower group=drug
name='scatter' ;*markerattrs=(symbol= asterisk);
discretelegend 'series' / title='Treatment' opaque=false border=true halign=left valign=bottom
displayclipped=true across=1 order=rowmajor location=inside
titleattrs=(family='Courier New' size=8 color= red);
/* Layout Overlay / walldisplay=none xaxisopts=(display=none);*/
/* xAxisTable VALUE=N X=week/ class=drug labelPosition=min Display=(Label);*/
/* endlayout;*/
endlayout;
endcell;
cell;
cellheader;
endcellheader;
/*innermargin;*/
** tattisk is the time variable where n at risk will be presented;
** atrisk is variable with number of patients at risk;
blockplot x = week block = n / class =drug
display=(values label) REPEATEDVALUES = true
EXTENDBLOCKONMISSING= true valuehalign = start
valueattrs=(size =7.5) labelattrs=(size = 7.5);
/**
axistable x = &tatrisk value = &natrisk / class = &group display=(label)
colorgroup = &group valueattrs=(size=8) labelattrs=(size=8);
/**/
/* endinnermargin; */
endcell;
endlayout;
endgraph;
end;
run;
ods html;
ods graphics on/ width=9 in height=4.4 in ;
proc sgrender data=have template=series;
*format avisitn wkfmt.;
run;
ods _all_ close;
Try this:
proc template;
define statgraph series;
begingraph / BORDER=False ATTRPRIORITY=NONE datacontrastcolors=(orange purple) datasymbols=( circle Asterisk ) datalinepatterns= (1 4);* datacolors=(green blue) ;
layout lattice / rows = 2 rowgutter=10 columngutter=10 rowWEIGHTS = preferred;
layout overlay / xaxisopts=( label=('X axis label') tickvalueattrs=(family='Courier New' size=8 weight=bold) labelattrs=(family='Courier New' size=8 weight=bold) linearopts=( viewmin=0.0 viewmax=28.0 TICKVALUELIST=(0 1 2 4 8 10 12 16 20 24 28) TICKVALUEFITPOLICY=ROTATE )) yaxisopts=( label=('Yaxis label') labelattrs=(family='Courier New' size=8 weight=bold) tickvalueattrs=(family='Courier New' size=8 ) linearopts=( viewmin=-15.0 viewmax=5.0 tickvaluesequence=( start=-15.0 end=6.0 increment=5.0)));
seriesplot x=week y=Estimate / group=drug name='series' display=(markers) connectorder=xaxis;
scatterplot x=week y=Estimate / yerrorupper = upper yerrorlower = lower group=drug name='scatter' ;
discretelegend 'series' / title='Treatment' opaque=false border=true halign=left valign=bottom displayclipped=true across=1 order=rowmajor location=inside titleattrs=(family='Courier New' size=8 color= red);
endlayout;
Layout Overlay / walldisplay=none xaxisopts=(display=none);
AxisTable VALUE=N X=week/ class=drug labelPosition=min Display=(Label);
endlayout;
endlayout;
endgraph;
end;
run;
ods html;
ods graphics on/ width=9 in height=4.4 in ;
proc sgrender data=have template=series;
*format avisitn wkfmt.;
run;
ods _all_ close;
Thanks @DanH_sas . It worked. I have last question.
1. In the log I see the following warning, It 's not effecting any thing in the graph. So I can just ignore it?
Sorry, I didn't see that earlier. Just get rid of the "x", and the message will go away.
No problem. Thank you for your time. I really appreciate it.
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.