I'm trying to make a bubble map using PROC SGMAP. I have managed to get everything on the map (annotations aside), but for some reason the map looks distorted horizontally. I have attached two versions of the map, one with the openstreetmap option and one without. The one without openstreetmap looks correct, but the other one is noticeably wider and shorter. Here is my code:
proc sgmap
mapdata=wvcounties
maprespdata=counties
plotdata=mapdata;
/* openstreetmap; */
choromap group / mapid=county id=county name='counties';
bubble x=maplong y=maplat size=summercap /
fillattrs=(color=blue)
datalabel=mapname
datalabelattrs=(color=black size=9 style=italic);
keylegend 'plants' / title='Plant Name';
run;
Attached are the two versions of the map.
The key to using Proc Gproject with SGmap, is that you have to drop the lat/long variables (if the map dataset has lat/long, then SGmap will use those instead of the projected x/y). Here's a small example to demonstrate:
data mymap; set mapsgfk.us_states (where=(statecode not in ('AK' 'HI')));
run;
proc gproject data=mymap out=mymap latlong eastlong degrees project=gnomon;
id statecode;
run;
title "Without dropping lat/long, lat/long is used";
proc sgmap mapdata=mymap maprespdata=sashelp.us_data;
choromap population_2010 / mapid=statecode;
run;
title "If you drop lat/long, then projected x/y is used";
proc sgmap mapdata=mymap (drop=lat long) maprespdata=sashelp.us_data;
choromap population_2010 / mapid=statecode;
run;
When using an Openstreetmap background, Proc SGmap applies a projection to your lat/long coordinates so they will line up correctly with the background map (I believe it is a pseudo-Mercator projection). When using an Openstreetmap background, you have no option/choice in the matter ... SGmap must project your coordinates to match that map. 🙂
When just drawing the choropleth map polygons (without the OpenStreetmap background), SGmap has more flexibility. If your map data has lat/long, then SGmap plots them by default (I'm not 100% sure if it applies an automatic projection in that case), and if you drop the lat/long variables then SGmap can use projected X/Y variables instead (and you could pre-process your dataset with Proc Gproject, so that those X/Y values are in any projection you want).
Thanks for helping me focus on the projection of the map. I will look into using PROC GPROJECT to get a projection that meets my needs. I have used it before for PROC GMAP using some of the shape data built into SAS, but I couldn't figure out the best way to make use of it for the newer SGMAP.
The key to using Proc Gproject with SGmap, is that you have to drop the lat/long variables (if the map dataset has lat/long, then SGmap will use those instead of the projected x/y). Here's a small example to demonstrate:
data mymap; set mapsgfk.us_states (where=(statecode not in ('AK' 'HI')));
run;
proc gproject data=mymap out=mymap latlong eastlong degrees project=gnomon;
id statecode;
run;
title "Without dropping lat/long, lat/long is used";
proc sgmap mapdata=mymap maprespdata=sashelp.us_data;
choromap population_2010 / mapid=statecode;
run;
title "If you drop lat/long, then projected x/y is used";
proc sgmap mapdata=mymap (drop=lat long) maprespdata=sashelp.us_data;
choromap population_2010 / mapid=statecode;
run;
This worked, thanks! For anyone who finds this later, though, I did have to combine the map boundaries and bubble points together before projecting in order to get them to line up properly on the map. But otherwise, this worked well!
You don't have to combine the map boundary and bubbles. Many years ago you did, but we now provide a way to save the projection parameters (using parmout=) and then use those parameters (using parmin=) when you project other datasets. Here's a little example:
data mymap; set mapsgfk.us_states (where=(statecode not in ('AK' 'HI')));
run;
proc gproject data=mymap out=mymap latlong eastlong degrees project=gnomon
parmout=projparm;
id statecode;
run;
data centers; set mapsgfk.uscenter (where=(statecode not in ('AK' 'HI') and ocean^='Y'));
run;
proc gproject data=centers out=centers latlong eastlong degrees
parmin=projparm parmentry=mymap;
id;
run;
title "Map and Centers projected separately";
proc sgmap mapdata=mymap (drop=lat long) maprespdata=sashelp.us_data
plotdata=centers;
choromap population_2010 / mapid=statecode;
scatter x=x y=y / markerattrs=(color=red);
run;
Thanks, I didn't know about that option. It's much easier!
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.