dm 'clear log'; dm 'clear list'; goptions reset=all; run; quit; %annomac; ***************************************************************************; * Pat Sells here is your bubble plot example *; * Note that I have put the label for the points in the dataset *; * Program: GPLTBUBB.SAS *; * Purpose: To generate 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*; * Annomac listed at the top is required to load the *; * the circle annotate macro that is used *; * Assumptions: That y variable is called YVAR *; * That x variabels is called XVAR *; * If you change these variable names change them *; * throughout the program *; ***************************************************************************; * 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 a color dataset here that we will merge into the *; * circle annotate dataset down the line *; * This is done to allow each circle to have an individual color *; ***************************************************************************; data smallset; set anno1; n=1; keep color n; run; quit; ********************************************************************************; * 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 *; * All of the circles will be the color red at this point because the circle *; * annotate macro can only have 1 color at a time. We will fix that in a later *; * datastep down the line *; ********************************************************************************; 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; %circle(x,y,bubsize2,red); output; run; proc print data=anno2; run; ********************************************************************************; * we then run a datastep on the annotated circle data *; * this creates a variable to merge the color dataset with *; * we then merge the color datastep by that variable in the next datastep *; * The proc sort is used to eliminate duplicate values generated by the circle *; * annotate macro *; ********************************************************************************; data anno2; set anno2; n=1; run; quit; proc sort nodup data=anno2; by xvar yvar; run; data anno2a; merge anno2 smallset; by n; ********************************************************************************; * 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 anno2a 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 *; *****************************************************************; 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 f=swissl a=90 'elasticity'); axis1 minor=(n=9) label=(c=red f=swissl '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;