Data visualization with SAS programming

Fun w/SAS ODS Graphics: SASGF 1976-2020 Host Cities

Reply
Contributor tc
Contributor
Posts: 74

Fun w/SAS ODS Graphics: SASGF 1976-2020 Host Cities

SASGF_LOCATIONS.gif

 

Ever wonder which cities are the most popular SASGF hosts? Well, wonder no more! Drawn from past, present, and future SASGF conference location info, here's a short program that creates a SAS ODS Graphics scatter plot showing SASGF 1976-2020 host cities together with markers for the years they've hosted a conference, the attendance for each year, and the total number of conferences hosted. The cities, which are ordered by the most recent year they hosted SASGF, include many one-hit wonders, as well as perennial favorites Orlando (6), San Francisco (4), Dallas (4), and Las Vegas (4). Believe it or not, this isn't the first time I've taken a crack at visualizing SASGF location data - check out Fit-to-a-T: Using SAS to Create a SAS Global Forum 2011 T-Shirt for a SAS/GRAPH (PROC GMAP) take on things!

 

CODE

* Fun w/SAS ODS Graphics: Scatter Plot of SASGF 1976-2020 Host Cities;

proc format;                                                  * Attendance, year formats;
picture attendf .='?' other='0,000';
picture yearf other='99';

data SASGFlocations;                                          * Read past/present/future SASGF info;
infile "/folders/myfolders/SASGFconferences.txt" truncover;
input ConferenceName $30. / ConferenceDates $30. / City $30. / Attendees;
Year=input(trim(scan(ConferenceDates,-1)),4.); 

proc sql;                                                     * Append # of conferences hosted;
create table SASGFlocationsFREQ as
select t1.city, put(attendees,attendf.) as AttendeesF, t1.year format=yearf., t2.FREQ 
from SASGFlocations t1, (select city, count(*) as FREQ from SASGFlocations group by 1) t2
where t1.city=t2.city;
                             
ods listing image_dpi=300 gpath='/folders/myfolders';         * Create 12"x7" scatter plot!;                                   
ods graphics / reset=all width=12in height=7in imagefmt=GIF antialias imagename="SASGF_LOCATIONS";
proc sgplot data=SASGFlocationsFREQ; 
title height=10pt "SAS GLOBAL FORUM HOST CITIES & ATTENDANCE (1976-2020)";       
scatter x=year y=City / datalabel=attendeesF datalabelpos=right datalabelattrs=(size=7pt) markerattrs=(symbol=circlefilled) labelstrip;
xaxis grid display=(nolabel) valueattrs=(size=7pt) values=(1976 to 2020 by 1) offsetmin=.02 offsetmax=.02; 
yaxis grid display=(nolabel) valueattrs=(size=8pt);
yaxistable FREQ / titleattrs=(size=8pt) stat=mean nolabel location=outside position=right;

DATA

SAS Global Forum 2020
May 3 - 6, 2020
Las Vegas, NV
?
SAS Global Forum 2019
April 28 - May 1, 2019
Dallas, TX
?
SAS Global Forum 2018
April 8 - 11, 2018
Denver, CO
?
SAS Global Forum 2017
April 2 - 5, 2017
Orlando, FL
?
SAS Global Forum 2016
April 18 - 21, 2016 
Las Vegas, NV
4917 
SAS Global Forum 2015
April 26 - 29, 2015 
Dallas, TX
4488 
SAS Global Forum 2014
March 23 - 26, 2014 
Washington, DC 
4306 
SAS Global Forum 2013
April 28 - May 1, 2013 
San Francisco, CA
4118 
SAS Global Forum 2012
April 22-25, 2012 
Orlando, FL
3422 
SAS Global Forum 2011
April 4-7, 2011 
Las Vegas, NV
3408 
SAS Global Forum 2010
April 11-14, 2010 
Seattle, WA
2999 
SAS Global Forum 2009
March 22-25, 2009 
Washington, DC
3328 
SAS Global Forum 2008
March 16-19, 2008 
San Antonio, TX
3794 
SAS Global Forum 2007
April 16-19, 2007 
Orlando, FL
3655 
SUGI 31
March 26-29, 2006 
San Francisco, CA
4242 
SUGI 30
April 10-13, 2005 
Philadelphia, PA
3258 
SUGI 29
May 9 - 12, 2004 
Montreal, Quebec, CAN 
2987 
SUGI 28
March 30 - April 2, 2003 
Seattle, WA
3036
SUGI 27
April 14-17, 2002 
Orlando, FL 
3676
SUGI 26
April 22-25, 2001 
Long Beach, CA 
3720
SUGI 25
April 9-12, 2000 
Indianapolis, IN 
3000
SUGI 24
April 11-14, 1999 
Miami Beach, FL 
3775
SUGI 23
March 22-25, 1998 
Nashville, TN 
3000
SUGI 22
March 16-19, 1997 
San Diego, CA 
3000
SUGI 21
March 10-13, 1996 
Chicago, IL
3000 
SUGI 20
April 2-5, 1995 
Orlando, FL 
2600 
SUGI 19
April 10-13, 1994 
Dallas, TX
2500 
SUGI 18
May 9-12, 1993 
New York, NY 
3500 
SUGI 17
April 12-15, 1992 
Honolulu, HI
2500 
SUGI 16
February 17-20, 1991
New Orleans, LA
3500 
SUGI 15
April 1-4, 1990
Nashville, TN
3500 
SUGI 14
April 9-12, 1989 
San Francisco, CA 
4000 
SUGI 13
March 27-30, 1988
Orlando, FL 
3500 
SUGI 12
February 8-11, 1987 
Dallas, TX
2800 
SUGI 11
February 9-12, 1986
Atlanta, GA
2600 
SUGI 10
March 10-13, 1985 
Reno, NV
2500 
SUGI '84
March 18-21, 1984 
Hollywood Beach, FL 
2092 
SUGI '83
January 16-19, 1983 
New Orleans, LA
1656 
SUGI '82
February 14-17, 1982 
San Francisco, CA 
1322 
SUGI '81
February 8-11, 1981 
Lake Buena Vista, FL 
1020 
SUGI '80
February 18-20, 1980 
San Antonio, TX 
600 
SUGI '79
January 29-31, 1979 
Clearwater, FL 
500 
SUGI '78
January 30 - February 1, 1978 
Las Vegas, NV 
241 
SUGI '77
January 3-5, 1977 
New Orleans, LA 
200 
SAS.ONE '76
January 26-28, 1976 
Kissimmee, FL 
206
SAS Super FREQ
Posts: 1,078

Re: Fun w/SAS ODS Graphics: SASGF 1976-2020 Host Cities

[ Edited ]

Timely graph.  May I suggest a Bubble Plot with bubble size and color proportional to the attendance?

Valued Guide
Posts: 505

Re: Fun w/SAS ODS Graphics: SASGF 1976-2020 Host Cities


Other ways to present the data
Does SAS have a Southern prejudice, New York, Chicago once an no Los Angeles?
SASGF 1976-2020 Host Cities Ordered by Most Frequent Locations ============================================================== Orlando, FL + 88 95 02 08 12 San Francisco, CA + 82 89 06 13 New Orleans, LA + 77 83 91 Las Vegas, NV + 78 11 16 Dallas, TX + 87 94 15 Washington, DC + 09 14 Seattle, WA + 03 10 San Antonio, TX + 80 07 Nashville, TN + 90 98 San Diego, CA + 97 Reno, NV + 85 Philadelphia, PA + 05 New York, NY + 93 Montreal, Quebec, CAN + 04 Miami Beach, FL + 99 Long Beach, CA + 01 Lake Buena Vista, FL + 81 Kissimmee, FL + 76 Indianapolis, IN + 00 Honolulu, HI + 92 Hollywood Beach, FL + 84 Clearwater, FL + 79 Chicago, IL + 96 Atlanta, GA + 86 | ---+---------+---------+---------+---------+---------+-- 1970 1980 1990 2000 2010 2020 Year SASGF 1976-2020 Host Cities Ordered by Most Frequent Locations Location Frequency Year ======== ========= === Orlando, FL 5 1988 1995 2002 2008 2012 San Francisco, CA 4 1982 1989 2006 2013 Dallas, TX 3 1987 1994 2015 Las Vegas, NV 3 1978 2011 2016 New Orleans, LA 3 1977 1983 1991 Nashville, TN 2 1990 1998 San Antonio, TX 2 1980 2007 Seattle, WA 2 2003 2010 Washington, DC 2 2009 2014 Atlanta, GA 1 1986 Chicago, IL 1 1996 Clearwater, FL 1 1979 Hollywood Beach, FL 1 1984 Honolulu, HI 1 1992 Indianapolis, IN 1 2000 Kissimmee, FL 1 1976 Lake Buena Vista, FL 1 1981 Long Beach, CA 1 2001 Miami Beach, FL 1 1999 Montreal, Quebec, CAN 1 2004 New York, NY 1 1993 Philadelphia, PA 1 2005 Reno, NV 1 1985 San Diego, CA 1 1997 * to lazy to add attendance; data have; length loc $44; input; pre=substr(put(2017-_n_,4.),3,2); odr=2017-_n_; loc=_infile_; cards4; Las Vegas, NV Dallas, TX Washington, DC San Francisco, CA Orlando, FL Las Vegas, NV Seattle, WA Washington, DC Orlando, FL San Antonio, TX San Francisco, CA Philadelphia, PA Montreal, Quebec, CAN Seattle, WA Orlando, FL Long Beach, CA Indianapolis, IN Miami Beach, FL Nashville, TN San Diego, CA Chicago, IL Orlando, FL Dallas, TX New York, NY Honolulu, HI New Orleans, LA Nashville, TN San Francisco, CA Orlando, FL Dallas, TX Atlanta, GA Reno, NV Hollywood Beach, FL New Orleans, LA San Francisco, CA Lake Buena Vista, FL San Antonio, TX Clearwater, FL Las Vegas, NV New Orleans, LA Kissimmee, FL ;;;; run;quit; proc sql; create table frq as select count(*) as frq ,loc ,odr ,pre from have group by loc order by frq descending, loc, odr ;quit; proc report data=frq nowd list; cols ("SASGF 1976-2020 Host Cities Ordered by Most Frequent Locations" loc frq odr); DEFINE LOC / order FORMAT= $44. WIDTH=34 SPACING=2 LEFT "Location" order=data; DEFINE FRQ / order FORMAT= BEST9. WIDTH=9 SPACING=2 RIGHT "Frqquency" order=data; DEFINE ODR / SUM FORMAT= BEST9. WIDTH=9 SPACING=2 RIGHT "Year" ; RUN;quit; proc freq data=have order=freq ; tables loc / out=frq; run;quit; proc sql; select distinct quote(trim(loc)) into :loc separated by ' ' from frq order by frq ; quit; options ls=90 ps=50; proc plot data=frq; plot loc*odr=' ' $ pre / vaxis=&loc; run;quit;
Contributor tc
Contributor
Posts: 74

Re: Fun w/SAS ODS Graphics: SASGF 1976-2020 Host Cities

[ Edited ]

Good suggestion (and easy enough to change!). Looks good on $249 home laptop, be interesting to see how it looks on one of the 4K-resolution monitors at work. Smiley Happy

 

SASGF_LOCATIONS.gif

[click image to see full size version]

 

CODE

* Fun w/SAS ODS Graphics: Bubble Plot of SASGF 1976-2020 Host Cities;

proc format;                                                  * Attendance, year formats;
picture attendf 0='TBD' other='0,000';
picture yearf other='99';

data SASGFlocations;                                          * Read past/present/future SASGF info;
infile "/folders/myfolders/SASGFconferences.txt" truncover;
input ConferenceName $30. / ConferenceDates $30. / City $30. / Attendees;
Year=input(trim(scan(ConferenceDates,-1)),4.);
if attendees=. then attendees=0; 

proc sql;                                                     * Append # of conferences hosted;
create table SASGFlocationsFREQ as
select t1.city, attendees, put(attendees,attendf.) as AttendeesF, t1.year format=yearf., t2.FREQ 
from SASGFlocations t1, (select city, count(*) as FREQ from SASGFlocations group by 1) t2
where t1.city=t2.city;
                             
ods listing image_dpi=300 gpath='/folders/myfolders';         * Create 20"x14" bubble plot!;                                   
ods graphics / reset=all width=20in height=14in imagefmt=GIF antialias imagename="SASGF_LOCATIONS";
proc sgplot data=SASGFlocationsFREQ; 
title height=14pt "SAS GLOBAL FORUM 1976-2020 HOST CITIES AND NUMBER OF ATTENDEES";       
bubble x=year y=City size=attendees / 
      colormodel=(deepskyblue darkblue) colorresponse=attendees bradiusmin=.125in datalabel=attendeesF
      datalabelpos=center datalabelattrs=(size=7pt weight=bold color=white) dataskin=crisp;
gradlegend / notitle;
xaxis grid display=(nolabel) valueattrs=(size=7pt weight=bold) values=(1976 to 2020 by 1) offsetmin=.02 offsetmax=.02; 
yaxis grid display=(nolabel) valueattrs=(size=9pt weight=bold);
yaxistable FREQ / valueattrs=(size=9pt weight=bold) stat=mean nolabel location=inside position=right;

 

 

Trusted Advisor
Posts: 1,506

Re: Fun w/SAS ODS Graphics: SASGF 1976-2020 Host Cities

Quick and dirty. Larger is more crowd, fainter is older.

data ATTENDANCE;
  infile cards pad;
  input NAME $32.
      /  @', ' YEAR 4.
      / CITY $32. 
      / ATTENDANCE 6.;
  STATECODE=left(scan(CITY,2,','));
  CITY=scan(CITY,1,',');
cards;

run;

proc sql;
  create table COORDINATES as select * 
  from ATTENDANCE 
         left join 
       MAPS.USCITY
         on  ATTENDANCE.CITY      = USCITY.CITY 
         and ATTENDANCE.STATECODE = USCITY.STATECODE
         and USCITY.FEATYPE       = 'city'  
  where ATTENDANCE.STATECODE not in ('HI' 'AK' 'PR' 'Quebec')
  order by ATTENDANCE;
quit;  

data ANNO;
  set COORDINATES; 
  retain FUNCTION 'pie     ' XSYS YSYS '2' ROTATE 360  WHEN 'A'
        STYLE 'psolid' ;    
  COLOR=cat('Aff0000',20+2017-YEAR); %* Aff does alpha-transparency ;
  SIZE=sqrt(ATTENDANCE/3.14)*.08;
run;
                       
goptions device=png xpixels=600 ypixels=480;
pattern c=cxeeeeff;
ods html;
proc gmap data= MAPS.US map= MAPS.US anno=ANNO all;  
  where STATECODE not in ('HI' 'AK' 'PR' );
  id STATE; 
  choro STATE / levels=1 nolegend;
run;
ods html close;

aaa1.PNG

 

Trusted Advisor
Posts: 1,506

Re: Fun w/SAS ODS Graphics: SASGF 1976-2020 Host Cities

Adding an outer border allows better a view of the multiple occurrences.

 


proc sql;
  create table COORDINATES as select * 
  from ATTENDANCE 
         left join 
       MAPS.USCITY
         on  ATTENDANCE.CITY      = USCITY.CITY 
         and ATTENDANCE.STATECODE = USCITY.STATECODE
         and USCITY.FEATYPE       = 'city'  
  where ATTENDANCE.STATECODE not in ('HI' 'AK' 'PR' 'Quebec')
  order by ATTENDANCE desc;
quit;  

data ANNO;
  set COORDINATES; 
  retain FUNCTION 'pie     ' XSYS YSYS '2' ROTATE 360  WHEN 'A'   ;
  STYLE='psolid' ;    
  COLOR=cat('Aff0000',20+2017-YEAR); %* Aff for alpha-transparency ;
  SIZE=sqrt(ATTENDANCE/3.14)*.1;
  output;
  STYLE='pempty' ;    
  COLOR='cx777777' ;
  output;
run;

 

aaa1.PNG

Community Manager
Posts: 2,691

Re: Fun w/SAS ODS Graphics: SASGF 1976-2020 Host Cities

I like it @ChrisNZ! But you left out Hawaii and Montreal!  Your approach might evoke the image of an erupting volcano for those who attended... (alas, before my time).

Trusted Advisor
Posts: 1,506

Re: Fun w/SAS ODS Graphics: SASGF 1976-2020 Host Cities

 @ChrisHemedingerThank you!

Nothing fancy, but I wanted to keep the amount of code (and my time) to a minimum, so the lower 48s were enough for the PoC.

To me it evokes more a map of earthquakes, similar to the map on this page.

A matter of where one lives probably... Smiley Happy

 

 

 

Ask a Question
Discussion stats
  • 7 replies
  • 770 views
  • 15 likes
  • 5 in conversation