Maps with ggplot2

Filed under: R,Tutorials — Lisa @ 4:52 pm July 30, 2011

The package “maps” contains geographical information very useful for producing maps, and it’s fairly easy to use this to make plots in ggplot2. This is a short tutorial showing how to create a map with shaded areas, like the one below.



To start off, we’ll need to import both of our required packages.

> require(maps)
> require(ggplot2)

The maps package won’t be called directly. Instead, the function map_data in ggplot2 obtains geographical information about a region from the package, and transforms it into a format that ggplot2 can understand. For example, map_data('state') gives us an ordered list of longitude and latitude points that outlines each US state.


> us_state_map <- map_data('state')
> head(us_state_map)
long lat group order region subregion
1 -87.46201 30.38968 1 1 alabama <NA>
2 -87.48493 30.37249 1 2 alabama <NA>
3 -87.52503 30.37249 1 3 alabama <NA>
4 -87.53076 30.33239 1 4 alabama <NA>
5 -87.57087 30.32665 1 5 alabama <NA>
6 -87.58806 30.32665 1 6 alabama <NA>

 

This tells us what each state boundaries are. We can then add our own data to determine how much to shade each region.


> states = c("alabama","arizona","arkansas","california",
"colorado","connecticut","delaware","district of columbia",
"florida","georgia","idaho","illinois",
"indiana","iowa","kansas","kentucky",
"louisiana","maine","maryland","massachusetts",
"michigan","minnesota","mississippi","missouri",
"montana","nebraska","nevada","new hampshire",
"new jersey","new mexico","new york","north carolina",
"north dakota","ohio","oklahoma","oregon",
"pennsylvania","rhode island","south carolina","south dakota",
"tennessee","texas","utah","vermont",
"virginia","washington","west virginia","wisconsin",
"wyoming")
> dataset <- data.frame(region=states,val=runif(49, 0,1))

 

If you’re using your own data set, it should be structured in a data frame as follows.


> head(dataset)
region val
1 alabama 0.2448814
2 arizona 0.1578860
3 arkansas 0.2455390
4 california 0.9446126
5 colorado 0.1861314
6 connecticut 0.4516558

 

Now we can merge our data set into the map data, and sort it again so that the points maintain the same order.


> map_data <- merge(us_state_map, dataset, by='region', all=T)
> map_data <- map_data[order(map_data$order), ]
> head(map_data)
region long lat group order subregion val
1 alabama -87.46201 30.38968 1 1 <NA> 0.2448814
2 alabama -87.48493 30.37249 1 2 <NA> 0.2448814
3 alabama -87.52503 30.37249 1 3 <NA> 0.2448814
4 alabama -87.53076 30.33239 1 4 <NA> 0.2448814
5 alabama -87.57087 30.32665 1 5 <NA> 0.2448814
6 alabama -87.58806 30.32665 1 6 <NA> 0.2448814

 

And with that, we are ready to generate the map!


> (qplot(long, lat, data=map_data, geom="polygon", group=group, fill=val)
+ theme_bw() + labs(x="", y="", fill="")
+ scale_fill_gradient(low='#EEEEEE', high='darkgreen')
+ opts(title="I was created using gplot2!",
legend.position="bottom", legend.direction="horizontal"))

Putting it all together, we have the following code


require(maps)
require(ggplot2)
states = c("alabama","arizona","arkansas","california",
"colorado","connecticut","delaware","district of columbia",
"florida","georgia","idaho","illinois",
"indiana","iowa","kansas","kentucky",
"louisiana","maine","maryland","massachusetts",
"michigan","minnesota","mississippi","missouri",
"montana","nebraska","nevada","new hampshire",
"new jersey","new mexico","new york","north carolina",
"north dakota","ohio","oklahoma","oregon",
"pennsylvania","rhode island","south carolina","south dakota",
"tennessee","texas","utah","vermont",
"virginia","washington","west virginia","wisconsin",
"wyoming")
dataset <- data.frame(region=states,val=runif(49, 0,1))
us_state_map <- map_data('state')
map_data <- merge(us_state_map, dataset, by='region', all=T)
map_data <- map_data[order(map_data$order), ]
(qplot(long, lat, data=map_data, geom="polygon", group=group, fill=val)
+ theme_bw() + labs(x="", y="", fill="")
+ scale_fill_gradient(low='#EEEEEE', high='darkgreen')
+ opts(title="I was created using gplot2!",
legend.position="bottom", legend.direction="horizontal"))

  • msgc

    wonderful post, thank you so very much, you made it look almost too easy!!! great job!

  • Angus

    I am learning how to maake maps in R and your example surfaced. I following along with your example, but i am running into an issue.

    When i run:
    dataset <- data.frame(region=states,val=runif(49, 0,1))
    head(dataset)

    My results are totally different from yours, and is different every time.

    Therefore this does not work, and complains with an error:
    map_data <- merge(us_state_map, dataset, by='region', all=T)

    Error: id variables not found in data: 1:49 ########## etc..

    How can this be fixed?

    I have tried set.seed(), but that seems to be a wild goose chase.

    Any help kindly appreciated.
    TIA