Users frequently ask how to plot their data as markers on a map. There are several ways to do this using SAS software. If you're a Visual Analytics user, you can do it using a point-and-click interface. But if you're a coder, you might need a little help... In this example, I show the basics of coding it using both Proc GMap and Proc SGplot.
Zip code Coordinates
The first thing you'll need to do is determine a latitude/longitude coordinate for the locations where you want markers. One way to do this is to use Proc Geocode. Depending on how much detail you have about the spatial location of your markers, you can use Proc Geocode to estimate the lat/long at the city, zip code, or street-level. In this simple example, I'm using zip codes. Here's the basic SAS code:
data locations; input Zip; anno_flag=1; datalines; 3901 20601 1001 27513 ; run; proc geocode data=locations out=locations (rename=(x=long y=lat)) method=ZIP lookup=sashelp.zipcode; run;
Preparing the Map
We ship several map datasets with SAS/Graph. Each line (row) of data describes 1 point along the border of an area in the map. The density of points along the borders is usually more than you need, and therefore you might want to use the density variable to exclude points above a certain density level. You might also want to exclude certain map areas. Once you have the desired subset of a map dataset, you can combine it with the zip code data, project it (using Proc Gproject), and then split the two datasets apart again. Here's the basic code:
data my_map; set mapsgfk.us_states (where=(statecode not in ('AK' 'HI') and density<=3) drop=resolution); run; data combined; set my_map locations; run; proc gproject data=combined out=combined latlong eastlong degrees; id statecode; run; data my_map locations; set combined; if anno_flag=1 then output locations; else output my_map; run;
Proc GMap Version
SAS' traditional mapping software is Proc GMap (found in the SAS/Graph product). It was built for handling maps, and has many nice features included. To plot markers at the zip code locations, you first have to create an annotate dataset. For round markers, I like using the annotate pie function (alternatively, you can annotate characters from any font, or create custom markers). Here's the basic code for creating an annotate dataset:
data anno_locations; set locations; xsys='2'; ysys='2'; hsys='3'; when='a'; function='pie'; rotate=360; size=1.0; style='psolid'; color='yellow'; output; length html $300; html='title='||quote(trim(left(city))||'0d'x||trim(left(put(zip,z5.)))); style='pempty'; color='purple'; output; run;
Once you've created the annotate dataset, you simply specify it using the anno= option when you create your Proc GMap:
proc gmap data=my_map map=my_map anno=anno_locations; id statecode; choro segment / levels=1 nolegend coutline=gray99; run;
Proc SGplot Version
If you don't have the SAS/Graph product, you can also create maps with Proc SGplot (which is part of Base SAS), by using polygons, and overlay scatter plot markers at the zip code locations. You'll need to rename your markers' X & Y variables, so they're something different from the map's X & Y. And if you want the markers to have html mouse-over text, this is a good time to set that up.
data scatter_locations (rename=(x=zipX y=zipY)); set locations (keep = zip city x y); label city_zip='00'x; length city_zip $100; city_zip='= = = = ='||'0d'x||trim(left(city))||'0d'x||trim(left(zip)); run;
You'll then need to combine the map and marker datasets, and specify both a polygon and scatter statement when you run Proc SGplot:
data my_map; set my_map scatter_locations; run; proc sgplot data=my_map noborder noautolegend; polygon x=x y=y id=statecode_plus_segment / fill outline tip=none lineattrs=(color=gray99) fillattrs=(color=cxe8edd5); scatter x=zipX y=zipY / tip=(city_zip) filledoutlinemarkers markerattrs=(symbol=circlefilled size=13) markerfillattrs=(color=yellow) markeroutlineattrs=(color=purple); xaxis display=none; yaxis display=none; run;
As you might have guessed, I glossed over a few of the finer details in the above code. Here's a link to the complete code, if you'd like to see all the details, and experiment with plotting your own data. Note that you will need a SAS/Graph license to have access to the maps, Proc Geocode, and Proc Gproject. And you'll need a fairly recent version of SAS to be able to run Proc SGplot and generate the polygon map.
Click here to see more examples about creating maps with Proc SGplot!
Dec 2017 Update: An official Proc SGmap is now available!