Graphics

Base SAS: Graph Template Language
``````
%let gpath='.';
%let dpi=100;

/* Generate some simulated data */
data sines;
do i=0 to 160;
f1 = sin(0.025*i) - 1.5*cos(0.09*i + 5) + 0.6*sin(0.08*i + 19);
f2 = 3*sin(0.02*i + 20) - 1.3*sin(0.005*i+10);
f3 = 2*sin(0.04*i - 8) + 0.05*i;
f4 = 0.8*cos(0.03*i-8) + 3*sin(0.02*i+17);
f5 = 2*cos(0.04*i + 13) + 0.02*abs(i - 77);
f6 = 2*sin(0.027*i + 3) + sin(0.018*i);

f1 = abs(f1); f2 = abs(f2); f3 = abs(f3)/1.3;
f4 = abs(f4); f5 = abs(f5); f6 = abs(f6);
if f1 < 0.1 then f1 = 0;
if f4 < 0.1 then f4 = 0;

format time monYY.;
time = '01Jan1970'd + i;

output;
end;
run;

data sines_stack;
set sines;
b1L = 0;
b1U = b1L + f1;
b2L = b1U;
b2U = b2L + f2;
b3L = b2U;
b3U = b3L + f3;
b4L = b3U;
b4U = b4L + f4;
b5L = b4U;
b5U = b5L + f5;
b6L = b5U;
b6U = b6L + f6;

drop f1 f2 f3 f4 f5 f6;
run;

data sines_river;
set sines;
/* G0 = - 1/2 * sigma[1..n](Fi) */
b1L = -0.5*(f1 + f2 + f3 + f4 + f5 + f6);
b1U = b1L + f1;
b2L = b1U;
b2U = b2L + f2;
b3L = b2U;
b3U = b3L + f3;
b4L = b3U;
b4U = b4L + f4;
b5L = b4U;
b5U = b5L + f5;
b6L = b5U;
b6U = b6L + f6;

length label \$35;
if i = 45 then
do; ly = 0.5*(b1L + b1U); label="VOCs"; end;
else if i=36 then
do; ly = 0.5*(b2L + b2U ); label="Nitrogen Oxides"; end;
else if i=80 then
do; ly = 0.5*(b3L + b3U); label="Carbon Monoxide"; end;
else if i=47 then
do; ly = 0.5*(b4L + b4U); label="Sulfur Dioxide"; end;
else if i=130 then
do; ly = 0.5*(b5L + b5U); label="Particulate 1"; end;
else if i=55 then
do; ly = 0.5*(b6L + b6U); label="Particulate 2"; end;
else
do; ly = .; label=" "; end;

drop f1 f2 f3 f4 f5 f6;
run;

/* Minimized Deviation */
data sines_river_mindev;
set sines;
/* G0 = - 1/(n+1) * sigma[1..n]((n - i + 1)* Fi) */
b1L = -0.14*(6*f1 + 5*f2 + 4*f3 + 3*f4 + 2*f5 + 1*f6);
b1U = b1L + f1;
b2L = b1U;
b2U = b2L + f2;
b3L = b2U;
b3U = b3L + f3;
b4L = b3U;
b4U = b4L + f4;
b5L = b4U;
b5U = b5L + f5;
b6L = b5U;
b6U = b6L + f6;

length label \$35;
if i = 45 then
do; ly = 0.5*(b1L + b1U); label="VOCs"; end;
else if i=36 then
do; ly = 0.5*(b2L + b2U ); label="Nitrogen Oxides"; end;
else if i=80 then
do;ly = 0.5*(b3L + b3U); label="Carbon Monoxide"; end;
else if i=47 then
do; ly = 0.5*(b4L + b4U); label="Sulfur Dioxide"; end;
else if i=130 then
do; ly = 0.5*(b5L + b5U); label="Particulate 1"; end;
else if i=58 then
do; ly = 0.5*(b6L + b6U); label="Particulate 2"; end;
else
do; ly = .; label=" "; end;

drop f1 f2 f3 f4 f5 f6;
run;

/* Stacked Graphs. Byron L., Wattenberg M. IEEE InfoVis 2008 */
proc template;
define statgraph river;
dynamic dynTime "time"
dynLL1 "first lower limit" dynLU1 "first upper limit"
dynLL2 dynLU2 dynLL3 dynLU3 dynLL4 dynLU4 dynLL5 dynLU5 dynLL6 dynLU6
dynTitle dynFootNote;
begingraph / designWidth=7in designHeight=4.5in;
EntryTitle dynTitle;
layout overlay / cycleAttrs=true
xaxisopts=(offsetMin=0 offsetMax=0 label="Date" display=(line ticks tickvalues)
timeopts=(minorTicks=true interval=month tickvalueformat=monyy.))
yaxisOpts=(display=(line label)
label="Proportion of Air Pollutants");
%let dispFillAttrs = dataTransparency=0.5;
bandPlot x=dynTime limitLower=dynLL1 limitUpper=dynLU1 / name="f1" &dispFillAttrs ;
bandPlot x=dynTime limitLower=dynLL2 limitUpper=dynLU2 / name="f2" &dispFillAttrs ;
bandPlot x=dynTime limitLower=dynLL3 limitUpper=dynLU3 / name="f3" &dispFillAttrs ;
bandPlot x=dynTime limitLower=dynLL4 limitUpper=dynLU4 / name="f4" &dispFillAttrs ;
bandPlot x=dynTime limitLower=dynLL5 limitUpper=dynLU5 / name="f5" &dispFillAttrs ;
bandPlot x=dynTime limitLower=dynLL6 limitUpper=dynLU6 / name="f6" &dispFillAttrs ;

%let seriesVizAttrs = lineAttrs=(pattern=solid color=grey thickness=2px);
seriesPlot x=dynTime y=dynLL1 / &seriesVizAttrs ;
seriesPlot x=dynTime y=dynLL2 / &seriesVizAttrs ;
seriesPlot x=dynTime y=dynLL3 / &seriesVizAttrs ;
seriesPlot x=dynTime y=dynLL4 / &seriesVizAttrs ;
seriesPlot x=dynTime y=dynLL5 / &seriesVizAttrs ;
seriesPlot x=dynTime y=dynLL6 / &seriesVizAttrs ;
seriesPlot x=dynTime y=dynLU6 / &seriesVizAttrs ;

scatterPlot x=dynTime y=ly /
markerCharacter=label  markerAttrs=(color=black);

endlayout;
entryfootnote halign=left dynFootNote /* / textattrs=graphValueText(size=7)*/;
endgraph;
end;
run;

ods _all_ close;
ods listing gpath=&gpath image_dpi=&dpi style=listing;
ods graphics / reset imagename="ThemeRiver" width=6.93in height=3.15in;

proc sgrender template=river data=sines_river_mindev;
dynamic dynTime="time"
dynLL1="b1L" dynLU1="b1U"
dynLL2="b2L" dynLU2="b2U"
dynLL3="b3L" dynLU3="b3U"
dynLL4="b4L" dynLU4="b4U"
dynLL5="b5L" dynLU5="b5U"
dynLL6="b6L" dynLU6="b6U"
dynTitle="Theme River: Variation of Pollutants over Time"
dynFootNote="(Simulated data)  Stacked Graphs. Byron & Wattenberg. IEEE InfoVis 2008"
;
run;
/* Stacked Graphs. Byron L., Wattenberg M. IEEE InfoVis 2008*/
ods _all_ close;

``````