This should be a simple question. The proc template is used to create the graph output below. All I want to do is change the fill colors of the "COOLING" "REWARMING" and "POST WARMING" blocks at the top. I have played around with the data attribute maps in dataset form as well as using the discreteattrmap in Proc Template.
Can someone point me to how to work these options to get what I need.
The ideal is:
proc template; define statgraph Temperature_overall1 ; begingraph ; layout lattice / columns=1 rows=1 ; cell; layout lattice / rowweights=(.04 .96); blockplot x=&x. block=block / datatransparency=.3 valuefitpolicy=shrink labelposition=left display=(fill label outline values) valuehalign=center ; layout overlay /yaxisopts=(griddisplay=on labelattrs=(color=black) tickvalueattrs=(color=black) linearopts=( viewmin=30 viewmax=40 ) display=(Line ticks tickvalues)) xaxisopts=(labelattrs=(color=black) tickvalueattrs=(color=black) display=(Line ticks tickvalues) linearopts=( viewmin=0 viewmax=100 )) ; seriesplot x=&x. y=sub_avg / group=zsubjectid lineattrs=(color=black THICKNESS=1 pattern=1) markerattrs=(size=0) DATATRANSPARENCY=.6 ; referenceline x=cool_ref / lineattrs=(color=black pattern=2); referenceline x=warm_ref / lineattrs=(color=black pattern=2); annotate; endlayout; endlayout; endcell; endlayout; endgraph; end; run;
Didn't even know that was an option! Fantastic.
A follow up question - Using the Axistable statement in an innermargin block, i have been unable to get borders around individual cells like you can using the blockplot statement. But with the blockplot, it doesn't seem like there is a way to specifically or dynamically tell it which colors are to be in which blocks.
Outside of your recommendation, which works, is there a way to accomplish either borders around the Axistable cells or explicitly tell the blockplot what colors the cells should be based on the value inside them?
Discrete attribute maps can be used with block plots. Here is an example:
proc template; define statgraph block; begingraph / collation=binary; DiscreteAttrVar attrvar=MYID_AGE var=AGE attrmap="__ATTRMAP__MYID"; DiscreteAttrMap name="__ATTRMAP__MYID" /; Value "11" / fillattrs=( color=CXFF0000); Value "12" / fillattrs=( color=CXFFA500); Value "13" / fillattrs=( color=CXFFFF00); Value "14" / fillattrs=( color=CX008000); Value "15" / fillattrs=( color=CX0000FF); Value "16" / fillattrs=( color=CX800080); EndDiscreteAttrMap; layout overlay / yaxisopts=(labelFitPolicy=Split) xaxisopts=(discreteOpts=(tickvaluefitpolicy=SplitRotate)); SeriesPlot X=Name Y=Weight / primary=true display=(markers) LegendLabel="Weight" NAME="SERIES"; InnerMargin / align=bottom; BlockPlot X=Name Block=MYID_AGE / Display=( Fill Outline Values Label ) valueFitPolicy=split valueHAlign=center valueVAlign=center; EndInnerMargin; endlayout; endgraph; end; run; proc sort data=sashelp.class out=class; by age; run; proc sgrender data=class template=block; run;
Didn't even know that was an option! Fantastic.
Neither did I until today. 🙂
A follow up question - Using the Axistable statement in an innermargin block, i have been unable to get borders around individual cells like you can using the blockplot statement.
I don't see such an option in the documentation of the AXISTABLE statement.
Outside of your recommendation, which works, is there a way to ... explicitly tell the blockplot what colors the cells should be based on the value inside them?
This is a very good question. I'm not really familiar with the GTL. The block plots that I created in the past were done with the BLOCK statement of PROC SGPLOT. There I used the DATTRMAP= option of the PROC SGPLOT statement to reference a dataset assigning colors to values. I was surprised to see that in GTL the assignment seemed to rely on the order of values. Now, upon your follow-up question I remembered a very valuable trick that I learned earlier this year from this posting by Bruno_SAS: https://communities.sas.com/t5/SAS-Programming/Background-color-of-legend-in-sgplot/m-p/801686/highl... .
So I ran my old block plot program with the TMPLOUT= option (of the PROC SGPLOT statement) added. And -- voilà! -- the resulting .sas file revealed the secret how the value-based color assignment can be done in PROC TEMPLATE: Apparently you need to insert a section like
discreteattrvar attrvar=blockvar var=block attrmap="myattrmap"; discreteattrmap name="myattrmap"; value "COOLING" / fillattrs=(color=lightblue); value "REWARMING" / fillattrs=(color=lightorange); value "POST-WARMING" / fillattrs=(color=lightgray); enddiscreteattrmap;
after the BEGINGRAPH statement, where the names "blockvar" and "myattrmap" are arbitrary user-defined names, and then refer to the first of these names in the BLOCK= option of the BLOCKPLOT statement, i.e.
blockplot x=&x. block=blockvar / ...;
Edit: Oops, the master was faster.
Registration is open! SAS is returning to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team. Register for just $495 by 12/31/2023.
If you are interested in speaking, there is still time to submit a session idea. More details are posted on the website.
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.