| Date: | Fri, 26 Feb 2010 07:23:10 -0800 |
| Reply-To: | Bill McKirgan <bill.mckirgan@GMAIL.COM> |
| Sender: | "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU> |
| From: | Bill McKirgan <bill.mckirgan@GMAIL.COM> |
| Organization: | http://groups.google.com |
| Subject: | Re: Another way to fill between two lines using annotate ( like |
|
| Content-Type: | text/plain; charset=ISO-8859-1 |
On Feb 25, 5:07 pm, jhi...@AMGEN.COM ("Hixon, John") wrote:
> /*
>
> This is another way to get what bill.mckir...@GMAIL.COM was looking for.
>
> I just used the code he showed from Mike Z, and instead of using "AREAS" in the plot statement
> I used an annotate dataset and the PolyCont function to draw the enclosed areas.
>
> Of course, there is that small area of overlap, but, this was just a
> quick exercise to show another way to obtain 'the same' result.
>
> That's what so interesting about SAS: there are always about 10 ways to do
> the job, so, you're bound to find one that works for you.
>
> To draw the polygons, it is required to 'connect' the points in the correct
> order, so we form the annotate datasets in 4 steps, and then
> concatenate them together. I did not have time to comment the code
> much, but...you'll get the idea when you see the result.
>
> HTH?
>
> Cheers,
>
> John Hixon
> jhi...@amgen.com
>
> Code below: Mostly just taken from Mike and Bill's original soln..
>
> */
>
> proc format;
> value age
> 1 = '<20'
> 2 = '20-24'
> 3 = '25-29'
> 4 = '30-34'
> 5 = '35-39'
> 6 = '40-44'
> 7 = '45-49'
> 8 = '50-54'
> 9 = '55-59'
> 10= '60-64'
> 11= '65-69'
> 12= '70-74'
> 13= '75-79'
> 14= '80-84'
> 15= '85+'
> ;
> run;
>
> /* Admin Data from TK's chart (deidentified prior to posting to SAS- L)*/
> data foo;
> input y1 y2 @@;
> * set y3 to the lower of the two values;
> y3 = y1*(y1 le y2) + y2*(y2 lt y1);
> x + 1;
> datalines;
> .00 .00
> .01 .00
> .03 .01
> .04 .01
> .05 .02
> .06 .04
> .08 .06
> .08 .09
> .09 .16
> .15 .29
> .10 .15
> .08 .08
> .09 .06
> .07 .03
> .06 .02
> ;
> run;
> proc print data=foo;
> run;
>
> * Call annomac to allow annotation macros;
> %annomac;
> *First form only the 'top part' of the polygon where y1>y3.
> Note, y3 is the min(y1,y2);
> data annoMYa;
> length color$8 text$80 style$16 function$8 ;
> retain function 'draw' hsys '3' xsys '2' ysys '2' color 'Red' position '5' when 'A'
> style "MS" size 2;
> set foo(where=(y1 ge y3));
> if x ne . and y1 ne .;
> if _n_=1 then do;
> %poly(x,y1,red,M3N90,1);
> end;
> %polycont(x,y1,red);
> run;
> *Now sort the raw data so we have the x values in reverse order.
> We need this since now we are constructing the 'bottom' of the
> polygon we want to fill.;
> proc sort data=foo out=fooB;
> by descending x;
> run;
> *Now form only the 'bottom part' of the polygon where y1<y3;
> data annoMyb;
> length color$8 text$80 style$16 function$8 ;
> retain function 'draw' hsys '3' xsys '2' ysys '2' color 'Black' position '5' when 'A'
> style "MS" size 2;
> set fooB(where=(y3 le y1));
> if x ne . and y1 ne .;
> %polycont(x,y3,red);
> run;
> * Now we repeat for the 'second' plot, which is defined by y2
> *First form only the 'top part' of the polygon where y2>y3;;
> data annoMYa2;
> length color$8 text$80 style$16 function$8 ;
> retain function 'draw' hsys '3' xsys '2' ysys '2' color 'Black' position '5' when 'A'
> style "MS" size 2;
> set foo(where=(y2 ge y3));
> * if x ne . and y1 ne .;
> if _n_=1 then do;
> %poly(x,y2,blue,M2N0,1);
> end;
> %polycont(x,y2,blue);
> run;
> *Now form only the 'bottom part' of the polygon, where y2<y3;
> data annoMyb2;
> length color$8 text$80 style$16 function$8 ;
> retain function 'draw' hsys '3' xsys '2' ysys '2' color 'Black' position '5' when 'A'
> style "MS" size 2;
> set fooB(where=(y3 le y2));
> if x ne . and y2 ne .;
> %polycont(x,y3,blue);
> run;
> * concatenate all 4 of the annotate data sets together to draw the filled polygons.;
> data annoMy2B;
> set annoMya annoMyb annoMya2 annoMyb2;
> run;
>
> * Then make the plot as below;
>
> goptions vsize=6.5in hsize=8.0in device=png border;
> symbol1 c=black v=none i=none;
> symbol2 c=blue v=none i=none;
> symbol3 c=black v=none i=none;
> symbol4 c=blue v=square i=join l=1 w=2;
> symbol5 c=red v=dot i=join l=1 w=2;
> axis1 label=('AGE GROUP') offset=(1,1)pct minor=none order=1 to 15;
> axis2 label=(a=90 'PERCENTAGE IN COHORT') order=0 to 0.3 by 0.05 minor=(n=4);
> legend1 label=none value=('' '' '' 'MyHVs' 'Total Vs') down=5 mode=protect position=inside;
> title1 ls=1 'MHV vs Total V Age Distribution' ;
> proc gplot data=foo;
> plot (y3 y2 y1 y2 y1) * x / overlay annotate=annomy2B
> haxis=axis1 vaxis=axis2 legend=legend1;
> format x age.;
> run;quit;
>
> /*
> HTH?
> Cheers,
>
> John Hixon
> jhi...@amgen.com
>
> */
John,
Thanks for another solution to study. I agree, one of the neat things
about SAS is there's usually many different possible ways to achieve a
goal. This problem has yielded a good mix of methods that will help
me, and I hope others, learn more about SAS graph. I look forward to
trying this out as soon as I have some time.
Thanks again,
Bill McKirgan
|