BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
SASuserlot
Barite | Level 11

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;

SASuserlot_0-1659391465066.png

 

 

I am also looking to add the data at the bottom of the x axis  that represent the Y axis values .

SASuserlot_1-1659391727579.png

I was able to control colors and adding the data with PROC SGPLOT. Thank you for your time and inputs.

 

1 ACCEPTED SOLUTION

Accepted Solutions
DanH_sas
SAS Super FREQ

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;

View solution in original post

12 REPLIES 12
ballardw
Super User

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.

SASuserlot
Barite | Level 11

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?

SASuserlot_0-1659397574923.png

 

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;
DanH_sas
SAS Super FREQ

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

SASuserlot
Barite | Level 11

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.

SASuserlot_0-1659445504549.png

 

Jay54
Meteorite | Level 14

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: 

https://blogs.sas.com/content/graphicallyspeaking/2018/02/19/survival-plot-twist-using-sgplot-proced...

 

 

SASuserlot
Barite | Level 11

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.

DanH_sas
SAS Super FREQ

@SASuserlot , What do you see when you try the structure I gave you? Can you post your template?

SASuserlot
Barite | Level 11

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.

SASuserlot_0-1659466984976.png

 

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;
DanH_sas
SAS Super FREQ

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;
SASuserlot
Barite | Level 11

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?

SASuserlot_0-1659478044310.png

 

DanH_sas
SAS Super FREQ

Sorry, I didn't see that earlier. Just get rid of the "x", and the message will go away.

SASuserlot
Barite | Level 11

No problem. Thank you for your time. I really appreciate it.

SAS Innovate 2025: Call for Content

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!

Submit your idea!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 12 replies
  • 2262 views
  • 5 likes
  • 4 in conversation