dm 'clear log'; dm 'clear list'; goptions reset=all; run; quit; %annomac; ***************************************************************************; * Note that I have put the label for the points in the dataset *; * Program: GPLOTBUBD *; * Purpose: To generate solid bubbles of different colors *; * Things to note: Bubbles will NOT be the same size scale *; * as the real bubble statement. This uses and absolute *; * scale while the bubble statement uses a relative scale*; ***************************************************************************; * First we read in the data *; ***************************************************************************; data temp1; length bubcolor mylabel $ 8; call symput('bubcolor',bubcolor); input xvar yvar mylabel $ bubsize bubcolor; cards; 1 10 site1 5.3 red 2 25 site2 3.35 green 3 32 site3 15.2 blue 4 55 site4 3.3 cyan 5 75 site5 12.0 magenta 6 100 site6 9.3 yellow ; ***************************************************************************; * Then we create the labels for the points using the annotate procedure *; ***************************************************************************; * Some key points here. first, note the xsys and ysys are set to 2 *; * and then they are matched to the x and y variables in your data. *; * You should also note the position variable as well I change it *; * depending on the location of the x variable so the annotate label *; * does not run off the graph. See position in the annotate dictonary *; * chapter in your graph reference for more details. *; ***************************************************************************; data anno1; set temp1; length function color style $ 8; length text $ 15; function ='label'; when= 'a'; style= 'swissb'; xsys= '2'; ysys= '2'; hsys='2'; position= '1'; x = xvar; y = yvar; ***************************************************************************; * changed the annotate label position here *; ***************************************************************************; text=mylabel; color=bubcolor; output; run; ********************************************************************************; * Then we create the annotated circles. We divide the bubsize by 2 because *; * the circle call uses the radius to create the circle instead of the diameter *; ********************************************************************************; data anno2; set temp1; bubsize2=bubsize/2; length function color style $ 8; when= 'a'; style= 'swissb'; xsys= '2'; ysys= '2'; hsys='2'; position= '1'; x = xvar; y = yvar; function='pie'; size=bubsize2; pattern='solid'; color=bubcolor; rotate=360; run; proc print data=anno2; run; ********************************************************************************; * Then we create the statistic label that generates the value of bubsize on the*; * plot. I thought this would be useful as well *; ********************************************************************************; data anno3; set temp1; length color style $ 8; length function text $ 15; function ='label'; when= 'a'; style= 'swissb'; xsys= '2'; ysys= '2'; hsys='2'; position= '1'; x = xvar; y = yvar; text=('size='||left(put(bubsize,best8.))); position='d'; color=bubcolor; output; run; proc print data=anno3; run; **************************************************************************; * Then we put the annotate datasets together in this step *; **************************************************************************; data annoall; set anno1 anno2 anno3; run; **************************************************************************; * This algorithm here sets larger limits so all the bubbles will show up *; * and will not be clipped off *; **************************************************************************; proc means n min max data=temp1; var xvar yvar bubsize; output out=limits min(xvar)=minxvar min(yvar)=minyvar max(xvar)=maxxvar max(yvar)=maxyvar; ; *****************************************************************; * Once we know the limits we add some factors to increase the *; * plotting area so the annotation will always fit *; * We then merge it back into the original dataset *; * The algorithm here could be much fancier but this will work *; * will work in most circumstances *; *****************************************************************; data limits; set limits; n=1; minxvar=minxvar - (.10 * abs(maxxvar)); maxxvar=maxxvar + (.10 * abs(maxxvar)); minyvar=minyvar - (.10 * abs(maxyvar)); maxyvar=maxyvar + (.10 * abs(maxyvar)); run; data temp1; set temp1; n=1; run; data merge1; merge temp1 limits; by n; proc print data=merge1; run; ******************************************************************************; * now use the annotate dataset in your gplot *; * 1. Three variables are plotted *; * a. yvar * xvar - these are the actual values that are plotted *; * this is plotted 2x so we could have different *; * symbol colors *; * b. minyvar * minxvar - this stretches the axis in the lower left corner *; * so that the lowest values are included *; * c. maxyvar * maxxvar - this stretches the axis in the upper right corner *; * so that the highest values are included *; * 2. Note the symbol statements only plot the original values *; * the v=none forces the other 2 values not to be plotted. *; ******************************************************************************; title c=red 'Degredation of Roof Tiles'; axis2 minor=(n=9) label=(c=blue a=90 'elasticity'); axis1 minor=(n=9) label=('hardness'); proc gplot data=merge1 anno=annoall; plot yvar * xvar maxyvar * maxxvar=2 minyvar * minxvar=2/vaxis=axis2 haxis=axis1 overlay nolegend; symbol1 v=none i=none c=red ; symbol2 v=none i=none c=green; run; quit;