%let name=mission; filename odsout '.'; libname mydata '.'; /* These are the colors for the lines, and the color-coded line labels above the graph */ %let altitude_color=magenta; %let temperature_color=blue; %let humidity_color=purple; proc sql; /* Find the maximum altitude info and save in a macro variable */ select time into :max_alt_time from mydata.lathumid having altitude eq max(altitude); select altitude into :max_alt from mydata.lathumid having altitude eq max(altitude); /* Find the right-most data points and save in macro variables, data at max time (mt) */ select time into :mt_time from mydata.lathumid having time eq max(time); select temp into :mt_temp from mydata.lathumid having time eq max(time); select humid/100 into :mt_humid from mydata.lathumid having time eq max(time); quit; run; data plotdata; set mydata.lathumid; /* determine which 'leg' of the trip each data point is in (ascending, or descending) */ length leg $10; if time <= &max_alt_time then leg='ascending'; else leg='descending'; length temp_line humid_line $30; temp_line='temp_'||trim(left(leg)); humid_line='humid_'||trim(left(leg)); /* Find out how close each datapoint is to 30k, 60k, and 90k feet */ minus30=abs(altitude-30000); minus60=abs(altitude-60000); minus90=abs(altitude-90000); /* Divide the humidity by 100, so you can use the official percent format */ format humid percentn7.0; humid=humid/100; run; proc sql; /* Find the data points closest to 30k, 60k, and 90k altitude, in the ascending leg */ create table ascending as select * from plotdata where leg eq 'ascending'; select time into :asc_30 from ascending having minus30 eq min(minus30); select time into :asc_60 from ascending having minus60 eq min(minus60); select time into :asc_90 from ascending having minus90 eq min(minus90); /* Find the data points closest to 30k, 60k, and 90k altitude, in the descending leg */ create table descending as select * from plotdata where leg eq 'descending'; select time into :des_30 from descending having minus30 eq min(minus30); select time into :des_60 from descending having minus60 eq min(minus60); select time into :des_90 from descending having minus90 eq min(minus90); quit; run; /* This is the annotate stuff for the plot ... */ data anno_ref; length function color $8 style $20 text $30; when='a'; /* Annotate label for the top 'axis' */ function='label'; color="blue"; style='"arial/bold"'; xsys='1'; ysys='1'; x=6; y=100; position='3'; text='Altitude (ft)'; output; /* draw the black refline at max altitude */ line=1; color="yellow"; xsys='2'; ysys='1'; function='move'; x=&max_alt_time; y=0; output; function='draw'; y=100; output; /* function='label'; color="blue"; angle=90; position='c'; text=' '||trim(left(round(&max_alt/1000)))||'k'; output; */ /* Labels to left & right of max altitude line */ function='label'; angle=0; style='"arial"'; color="yellow"; position='d'; x=x-60; text='ascent >'; output; position='f'; x=x+120; text='descent >'; output; /* Draw the dashed reflines corresponding to 30k, 60k, 90k altitude in 1st plot */ line=1; color="blue"; xsys='2'; ysys='1'; function='move'; x=&asc_30; y=0; output; y=100.5; function='draw'; output; function='label'; angle=90; position='c'; text=' 30k'; output; xsys='2'; ysys='1'; function='move'; x=&asc_60; y=0; output; y=100.5; function='draw'; output; function='label'; angle=90; position='c'; text=' 60k'; output; xsys='2'; ysys='1'; function='move'; x=&asc_90; y=0; output; y=100.5; function='draw'; output; function='label'; angle=90; position='c'; text=' 90k'; output; xsys='2'; ysys='1'; function='move'; x=&des_90; y=0; output; y=100.5; function='draw'; output; function='label'; angle=90; position='c'; text=' 90k'; output; xsys='2'; ysys='1'; function='move'; x=&des_60; y=0; output; y=100.5; function='draw'; output; function='label'; angle=90; position='c'; text=' 60k'; output; xsys='2'; ysys='1'; function='move'; x=&des_30; y=0; output; y=100.5; function='draw'; output; function='label'; angle=90; position='c'; text=' 30k'; output; run; data anno_linelabel1; xsys='2'; ysys='2'; position='c'; color='yellow'; function='label'; when='a'; style='"arial/bo"'; x=&mt_time; y=&mt_temp; text=' Temperature'; run; data anno_linelabel2; xsys='2'; ysys='2'; position='c'; color='yellow'; function='label'; when='a'; style='"arial/bo"'; x=&mt_time; y=&mt_humid; text=' Humidity'; run; GOPTIONS DEVICE=png; ODS LISTING CLOSE; ODS HTML path=odsout body="&name..htm" (title="Near Space Ventures High Altitude Balloon Data (SAS/Graph chart)") options(pagebreak='no') style=minimal; goptions noborder; /* Change needed because v9.2 renders fonts larger */ * goptions htitle=20pt ftitle="arial/bold" htext=12pt ftext="arial" ctext=blue; goptions htitle=20pt ftitle="arial/bold" htext=10pt ftext="arial" ctext=blue; goptions colors=(blue); /* 1st color in the colorlist is used for axes */ axis1 order=('08:45:00't to '11:15:00't by 900) minor=none label=(f="arial/bo" 'Time') offset=(0,11); axis2 label=none minor=none offset=(.5,0) order=(-40 to 100 by 20); /* The recorded values show humidity < 0%, but since that's "impossible" I only have the axis go to 0% */ axis3 label=none minor=none offset=(.5,0) value=(justify=center) order=(0 to 1.20 by .20); title1 "Humidity & Temperature vs. Altitude by Time"; title2 h=11pt " "; title3 angle= 90 h=12pt f="arial/bo" "Temperature (F)"; title4 angle=-90 h=12pt f="arial/bo" "Humidity"; /* Needed because of a 9.2 bug where the axis values aren't left-justified */ title5 angle=-90 h=7pt " "; footnote j=left "Source: CNS_022, Near Space Ventures Inc." j=right "August 18, 2007"; symbol1 value=dot height=.5 interpol=line color=red; symbol2 value=dot height=.5 interpol=line color=cxee6363; symbol3 value=dot height=.5 interpol=line color=purple; symbol4 value=dot height=.5 interpol=line color=cx9370db; goptions xpixels=850 ypixels=550; proc gplot data=plotdata anno=anno_ref; format time time5.; plot temp*time=temp_line / haxis=axis1 vaxis=axis2 nolegend anno=anno_linelabel1 iframe='balloonInSky.jpg' imagestyle='fit' des="" name="&name"; plot2 humid*time=humid_line / vaxis=axis3 nolegend anno=anno_linelabel2 ; run; /* Print the data */ /* title; footnote; proc print data=plotdata noobs; format time time.; var time leg altitude humid temp; run; */ quit; ODS HTML CLOSE; ODS LISTING;