简体   繁体   中英

Complex Maps in R Using ggplot2

I recently needed to create a map using combined statistical areas for the US - I want to share how this can be done. The same applies if one wants to use zip codes or other divisions (county, congressional districts, etc.)

1) You need to obtain shapefiles that are needed by any program to draw a map - these basically define the polygons that create the shapes (states, zips, csa, etc.). In the US the Census bureau provides those at

http://www.census.gov/cgi-bin/geo/shapefiles2013/main

(I am sorry but these are so large that I can't provide the data for an example). Unzip them and place them into your directory of choice. Make sure you set it as the working directory using setwd()

2) The files need to be imported into a spatial dataframe object in R, using readShapeSpatial in package maptools. In my case I read 2 files, state to draw the boundary and the csa file to draw the metro areas. For simplicity I created an id field in each, this is not needed. Please note rgeos is required as well, by default maptools tries to use gpoclib but there are some license issues, rgeos doe snot have those

require(maptools)
require(rgeos)
cbsa_bdry = readShapeSpatial("tl_2013_us_csa.shp")
cbsa_bdry@data$id <- as.character(cbsa_bdry@data$GEOID)
state_bdry = readShapeSpatial("tl_2013_us_state.shp")
state_bdry@data$id <- as.character(state_bdry@data$STUSPS)

3) the files need to be fortified to be used in ggplot - as far as I can tell this is creating a dataffame for plotting from the spatial data set. I do not understand it but it is needed. Here you use the id field - in my case state and the csa number

cbsa_map_f <- fortify(cbsa_bdry, region="id")
state_map_f <- fortify(state_bdry, region="id")

At this point the fortified files can be mapped using ggplot, however normally you want some other data to be mapped with them, for example a variable of interest that defines the color of the shape (it can be say the party that holds the governor mansion, or the average income, or whatever your analysis dictates)

4) I will merge back the data portion of the spatial dataframe for this example, in this case I am not mergin any other data. Please note, I learned the hard way that using merge can mess up the data due to sorting, if you use merge make sure the data is not sorted as part of it, I am using join for that reason.

require(plyr)
state_map_df <-join(state_map_f, state_bdry@data, by="id")
state_map_df$state <- state_map_df$STUSPS

5) Do your chart - you need to draw the layers in order, the bottom layer first, then second one, or one can obscure the other. For simplicity I am only drawing Texas

tx <-subset(cbsa_map_df,state=="TX" )
tx1 <- subset(state_map_df,state=="TX")
require(ggplot2)
require(mapproj)

sample <- ggplot(NULL) +geom_polygon(data=tx1,aes(long,lat,group=group),color="blue",fill="light gray")+coord_map(projection="mercator")+theme_bw()
sample <- sample +    geom_polygon(data=tx,aes(long,lat,fill=NAME,group=group),color="black")+theme(legend.position="bottom",axis.text.x = element_blank(),axis.text.y = element_blank(),axis.ticks = element_blank())
sample<- sample+guides(fill=guide_legend(title="MSA Name",nrow = 3,title.position="top",title.hjust=0.5,title.theme=element_text(face="bold",angle=0)))
sample <- sample + scale_x_continuous("")+scale_y_continuous("")
sample

I am not passing a dataframne to the initial gplot call to open the chart as each layer uses a different dataframe for data. If I had merged data to use a continuous scale I would use that on the fill= for the csa portion

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM