In this recipe, we will learn how to plot data on regional maps within individual countries rather than the whole world map. We will look at examples based on the United States and European countries.
Just as with the previous recipe, we will make use of the maps
package to draw the map and the RColorBrewer
package to choose color schemes. So, let's make sure that they are loaded:
library(maps) library(RColorBrewer)
We will use the inbuilt USArrests
example dataset, which contains crime statistics, in arrests per 100,000 residents for assault, murder, and rape in each of the 50 US states in 1973.
Let's plot the arrests rate for murders in US states in 1973. The default graphics device size might not be big enough for the map; thus, if you get an error about figure margins, enlarge the graphics device:
x<-map("state",plot=FALSE) for(i in 1:length(rownames(USArrests))) { for(j in 1:length(x$names)) { if(grepl(rownames(USArrests)[i],x$names[j],ignore.case=T)) x$measure[j]<-as.double(USArrests$Murder[i]) } } colours <- brewer.pal(7,"Reds") sd <- data.frame(col=colours, values=seq(min(x$measure[!is.na(x$measure)]), max(x$measure[!is.na(x$measure)])*1.0001, length.out=7)) breaks<-sd$values matchcol<-function(y) { as.character(sd$col[findInterval(y,sd$values)]) } layout(matrix(data=c(2,1), nrow=1, ncol=2), widths=c(8,1), heights=c(8,1)) # Color Scale first par(mar = c(20,1,20,7),oma=c(0.2,0.2,0.2,0.2),mex=0.5) image(x=1, y=0:length(breaks),z=t(matrix(breaks))*1.001, col=colours[1:length(breaks)-1],axes=FALSE,breaks=breaks, xlab="", ylab="", xaxt="n") axis(4,at=0:(length(breaks)-1), labels=round(breaks),col="white",las=1) abline(h=c(1:length(breaks)),col="white",lwd=2,xpd=F) #Map map("state", boundary = FALSE,col=matchcol(x$measure), fill=TRUE,lty="blank") map("state", col="white",add = TRUE) title("Murder Rates by US State in 1973 (arrests per 100,000 residents)", line=2)
The example is similar to the previous recipe in its overall structure, but it differs mainly in the fact that we plotted data for one country's states. We used the USArrests
dataset, which is inbuilt in R and contains various crime figures by state for the United States.
Just as in the previous recipe, we first mapped the values of the chosen statistic (murder rates, in this case) to the corresponding region names (in this case, states) in the map
object created using the map()
function. We chose a red color scheme from RColorBrewer
.
Instead of creating a vector of colors for each of the values plotted, we defined a function matchcol()
that takes a value as an argument and uses the findInterval()
function to return a color value from the data frame, sd
, that contains the breaks and corresponding colors from the chosen palette.
We then created a two-column layout and drew the color scale first in the right column. Then, we plotted the map with fill
set to TRUE
and col
set to a function call to matchcol()
with x$measure
as the argument. We set the boundary to FALSE
, to draw white boundaries instead of the default black ones. We did so by calling map()
again with col
set to white and add set
to TRUE
. Finally, we used the title()
function to add a map title.
Mapping data by states is just one of the options in the maps
package for the United States. We can also map data by counties and regions defined as groups of specific states. For example, we can draw a county map of New York using the following line of code:
map("county", "new york")
Otherwise, we can draw a map with three states with:
map("state", region = c("california", "oregon", "nevada"))
Now, let's look at another example, this time from a European country:
map('italy', fill = TRUE, col = brewer.pal(7,"Set1"))
The preceding example uses the inbuilt dataset for Italy in the maps
package. We used the colors just to differentiate the various territorial units from each other; the colors do not represent any numerical quantity. The maps
package does not have geographical data for other countries. However, there is one good source for worldwide geographical data: the GADM database of Global Administrative Areas. One can freely download data for countries across the world in R's native RData format for noncommercial use from http://gadm.org.
The GADM data can be used in combination with the sp
package to plot regional data on maps. Let's look at an example of rainfall in France. First, let's make sure that the sp
package is installed and loaded:
install.packages("sp") library(sp)
Now, let's create some pseudo rainfall data for the French administrative regions and plot it on a map of France:
load(url("http://gadm.org/data/rda/FRA_adm1.RData")) gadm$rainfall<-rnorm(length(gadm$NAME_1),mean=50,sd=15) spplot(gadm,"rainfall", col.regions = rev(terrain.colors(gadm$rainfall)), main="Rainfall (simulated) in French administrative regions")
First, we loaded the geographical boundary data for France by calling the load()
function with a url
of the location of the dataset on the GADM website. In this case, the dataset loaded was FRA_adm1.RData
. This function call stores the data in an object called gadm
(you can verify this by typing in gadm
at the R prompt and hitting Enter). Next, we appended a vector of pseudo rainfall data to
gadm
by calling the rnorm()
function. Finally, we used the spplot()
function from the sp
package to plot the data. The first argument to the spplot()
function is the gadm
object itself and the second argument is the name of the variable we wish to plot on the map. We set the fill color of the regions using col.region
; this is slightly different from the map()
function because the sp
package is based on the lattice
library. We used a color
scheme based on the terrain.colors()
function, but reversed it with rev()
so that low to high rainfall is represented by gray through brown to green.
3.137.165.228