%let name=broadband_penetration; filename odsout '.'; /* My version of graph from: http://support.sas.com/resources/papers/proceedings13/309-2013.pdf ** Note that in the paper they hard-code annotated 'needle' lines, and one of the colored markers, and the legend (and mention that this is a disadvantage of using Gplot rather than the new SG stuff). But this example shows that those things can be done in a data-driven way in Gplot, without hard-coding the annotation! Using data from: http://en.wikipedia.org/wiki/List_of_countries_by_number_of_broadband_Internet_subscriptions */ /* used to control the bubble sizes */ %let maxbub=6; /* maximum bubble size */ %let maxval=95000000; /* guess at maximum population value */ /* dbms=xlsx reads in data as character */ PROC IMPORT OUT=my_data DATAFILE="broadband_penetration.xlsx" DBMS=EXCEL REPLACE; GETNAMES=YES; RUN; data my_data; set my_data; format DSL_pp Cable_pp Other_pp Total_pp percent7.0; format Total_subscribers comma20.0; label DSL_pp='DSL'; label Cable_pp='Cable'; label Other_pp='Other'; format pop_dsl pop_cable pop_other comma30.0; pop_dsl=(dsl_pp/total_pp)*total_subscribers; pop_cable=(cable_pp/total_pp)*total_subscribers; pop_other=(other_pp/total_pp)*total_subscribers; run; data anno_data; set my_data; length function $8 color $15 style $35 html $300; hsys='3'; when='a'; function='pie'; style='psolid'; rotate=360; xsys='2'; x=rank; ysys='2'; if dsl_pp^=. then do; y=dsl_pp; size=(sqrt(pop_dsl/3.14)/sqrt(&maxval/3.14))*&maxbub; style='psolid'; color="Aadb2d6aa"; output; html= 'href="broadband_penetration_info.htm"'|| ' title='||quote(trim(left(put(pop_dsl/1000000,comma10.1)))||' million people in '||trim(left(country))||' using DSL'); style='pempty'; color='gray99'; output; html=''; end; if cable_pp^=. then do; y=cable_pp; size=(sqrt(pop_cable/3.14)/sqrt(&maxval/3.14))*&maxbub; style='psolid'; color="Ae79e9caa"; output; html= 'href="broadband_penetration_info.htm"'|| ' title='||quote(trim(left(put(pop_cable/1000000,comma10.1)))||' million people in '||trim(left(country))||' using Cable'); style='pempty'; color='gray99'; output; html=''; end; if other_pp^=. then do; y=other_pp; size=(sqrt(pop_other/3.14)/sqrt(&maxval/3.14))*&maxbub; style='psolid'; color="Aa5cbc6aa"; output; html= 'href="broadband_penetration_info.htm"'|| ' title='||quote(trim(left(put(pop_other/1000000,comma10.1)))||' million people in '||trim(left(country))||' using Other'); style='pempty'; color='gray99'; output; html=''; end; function='label'; color='gray99'; position='5'; size=.; ysys='3'; y=20; text=trim(left(put(Total_subscribers/1000000,5.1))); output; y=16; text=trim(left(put(Total_pp*100,comma7.1))); output; run; data anno_labels; length text $100; xsys='1'; ysys='3'; hsys='3'; when='a'; function='label'; position='4'; color='gray99'; x=-1; y=20; text='Total subscribers in Millions'; output; y=16; text='% Population Online'; output; run; /* Create a data-driven user-defined-format, so the 'rank' will print as the country name. */ data control; set my_data (rename=(rank=start country=label)); fmtname='myfmt'; type='N'; run; proc format lib=work cntlin=control; run; goptions device=png; goptions xpixels=950 ypixels=600; goptions border; ODS LISTING CLOSE; ODS HTML path=odsout body="&name..htm" (title="Broadband Users by Country and Broadband Type") style=htmlblue; goptions gunit=pct ftitle="albany amt/bold" ftext="albany amt" htitle=3.25 htext=2.0; axis1 label=(a=90 'Percent Penetration') order=(0 to .35 by .05) minor=none offset=(10,0); axis2 label=none order=(1 to 15 by 1) minor=none offset=(5,3) value=(height=1.8); /* make country names a little smaller than default text, so they will fit without auto-rotating. */ /* The legend draws the colored dots, based on the 'needle' interpol symbols. You won't really see these dot markers at the top of the needles (because I make them very-very small), and then I annotate the colored bubbles. */ legend1 label=none across=3 position=(top right inside) cborder=grayaa mode=share shape=symbol(6,6) repeat=1; /* This is just to draw the 'needle' line from the markers to the base, and create the colored dots show up in the legend (I annotate the actual colored balls). */ symbol1 value=dot h=.001 c=Aadb2d6aa interpol=needle ci=graydd; /* blue */ symbol2 value=dot h=.001 c=Ae79e9caa interpol=needle ci=graydd; /* red */ symbol3 value=dot h=.001 c=Aa5cbc6aa interpol=needle ci=graydd; /* green */ title1 link="http://en.wikipedia.org/wiki/List_of_countries_by_number_of_broadband_Internet_subscriptions" ls=1.5 move=(+17,+0) "Broadband Users by Country and Broadband Type (~2010)"; title2 a=90 h=12 ' '; title3 a=-90 h=2 ' '; footnote1 j=r move=(-3,+0) c=gray "Bubble size represents number of people in that country using that broadband technology"; footnote2 j=r move=(-3,+0) c=gray ls=1.0 "Countries ordered (left-to-right) by total broadband subscribers"; proc gplot data=my_data anno=anno_data; format rank myfmt.; plot dsl_pp*rank=1 cable_pp*rank=2 other_pp*rank=3 / overlay vaxis=axis1 haxis=axis2 vref=0 legend=legend1 anno=anno_labels des='' name="&name"; run; quit; ODS HTML CLOSE; ODS LISTING;