Reputation: 1764
I have a dataset I am working with that is very similar to the one created below. I want to graph the yearly trend in score by state, on the same graph. Additionally, I want to shade a portion of the graph where something happened (in this case a drop in score). Let's say I expected this event to be between 2011 and 2013. I want to shade a light gray rectangle over those years. I think my code is close, but cannot quite get the syntax correct.
Any help accomplishing this would be greatly appreciated. Also, any recommendations on cleaning up the proc template statements (are both needed? or can I combine into one?). Thanks.
Edit: the main issue, I think, is the syntax of the annorec data step.
data statescores;
input state $ year score;
cards;
NC 2010 75
NC 2011 77
NC 2012 72
NC 2013 85
NC 2014 87
SC 2010 72
SC 2011 73
SC 2012 60
SC 2013 79
SC 2014 76
VA 2010 80
VA 2011 80
VA 2012 79
VA 2013 81
VA 2014 83
;
run;
data drop;
input startdate enddate;
datalines;
2011 2013
;
data annorec;
/* length function style color $8; */
retain xsys '2' ysys '1' when 'b';
set drop;
function='rectangle';
height=.4;
width=2;
x=startdate;
y=60;
display="all";
FILLCOLOR='LTGRAY';
output;
/* function='bar'; */
/* x=enddate; */
/* y=90; */
/* color='ltgray'; */
/* style='solid'; */
/* output; */
run;
proc template;
define style styles.stocks;
parent=styles.listing;
style GraphData1 from GraphData1 /
ContrastColor=blue
Color=red
MarkerSymbol="CircleFilled"
Linestyle=1;
style GraphData2 from GraphData2 /
ContrastColor=brown
Color=blue
MarkerSymbol="none"
Linestyle=2;
style GraphData3 from GraphData3 /
ContrastColor=orange
Color=orange
MarkerSymbol="none"
Linestyle=2;
end;
run;
proc template;
define statgraph trend;
begingraph;
entrytitle "Scores for NC, SC, and VA";
discreteattrmap name="stockname" / ignorecase=true;
value 'NC' /
markerattrs=GraphData1(color=red symbol=circlefilled)
lineattrs=GraphData1(color=red pattern=solid);
value 'SC' /
markerattrs=GraphData2(color=orange)
lineattrs=GraphData2(color=green pattern=dot);
value 'VA' /
markerattrs=GraphData3(color=blue)
lineattrs=GraphData3(color=blue pattern=dot);
enddiscreteattrmap;
discreteattrvar attrvar=stockmarkers var=stock
attrmap="stockname";
layout overlay;
seriesplot x=year y=score /
group=state
display=(markers)
name="scores";
discretelegend "scores" / title="State Scores";
endlayout;
endgraph;
end;
run;
/* Plot the score trends */
ods pdf file="/sasdata/username/testgraph.pdf";
ods pdf style=styles.stocks;
proc sgrender data=statescores template=trend sganno=annorec;
run;
quit;
ods pdf close;
Upvotes: 0
Views: 991
Reputation: 63424
I would try to avoid using a discrete attribute map in GTL if you can avoid it. If you have only a few states, you really don't need it; even in your code above it does little other than to override some things you set in the earlier template step. Attribute maps are nice for SGPLOT, but are a pain in GTL in my experience.
In this case, you should try to use the BAND plot to make your gray band. Play with it some, but this should basically give you what you want:
proc sgplot data=statescores;
series x=year y=score/ group=state;
band y=score upper=2013 lower=2011 /transparency=0.8 ;
run;
That makes a pretty nice looking plot with four lines of code, plus if you want to add the colors you can fairly easily (either in an attribute map dataset, or in template code). In general, annotate datasets are often unnecessary in the SGPlot/GTL world, as you can layer plots easily and a lot of annotation can be done via layered plots instead.
If you want more detailed code review, I suggest posting in communities.sas.com, where some of the graph developers who work at SAS will often give suggestions on improvements to code.
Upvotes: 1