Creating graphs with regional maps

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.

Getting ready

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.

How to do it...

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)
How to do it...

How it works...

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.

There's more

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"))
There's more

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")
There's more

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.165.228