I'm making a choropleth map with added points in ggplot. So, following the last example of the geom_map help docs
I came up with this:
require(ggplot2)
require(maps)
set.seed(47)
county_map <- map_data("county", "washington")
names(county_map)[5:6] <- c("state", "id")
countyData <- data.frame(id = unique(county_map$id), value = rnorm(39))
map1 <- ggplot(countyData, aes(map_id = id)) +
geom_map(aes(fill = value), map = county_map, colour = "black") +
coord_map() +
expand_limits(x = county_map$long, y = county_map$lat)
print(map1)
which works great for the choropleth map. (Aside that I'm thrilled with the map_data
function.) But then I try and add points
pointData <- structure(list(xx = c(-119.872483243387, -122.809038239929,
-122.143143065312
), yy = c(48.1320425447619, 46.7352071436801, 47.9911548514037
)), .Names = c("xx", "yy"), row.names = c(1746L, 7281L, 2692L
), class = "data.frame")
map1 + geom_point(mapping = aes(xx, yy), data = pointData)
And I can't get it to work. I tried a lot of variations, setting group
to NULL
, naming aes
arguments, etc. No luck. So I find this question which does the exact same thing without a problem by merging the map data with the choropleth data and using geom_polygon
, which seems more straightforward anyway. (It took me a little while to work out the ID mapping in the first place because I didn't realize I had to remove the region
column name to successfully use id
. And the syntax of the first method still seems weird to me.)
So, two questions:
- How is it possible to add points from a different data frame using the method shown above with
geom_map
? - More importantly, are there any advantages to using
geom_map
as opposed to thegeom_polygon
approach?
Your immediate problem is that ggplot
has no way to tie your point data to the map. Looking at your data frames, you have this for your map:
str(countyData)
'data.frame': 39 obs. of 2 variables:
$ id : chr "adams" "asotin" "benton" "chelan" ...
$ value: num 1.995 0.711 0.185 -0.282 0.109 ...
...and this for your points:
str(pointData)
'data.frame': 3 obs. of 2 variables:
$ xx: num -120 -123 -122
$ yy: num 48.1 46.7 48
Do you see any common variables there that would allow ggplot
to locate your points?
Still, the problem is easily resolved. I typically use geom_polygon
rather than geom_map
but that's largely out of habit. This works, for example:
colnames(pointData) <- c('long','lat') # makes consistent with county_map
pointData$group <- 1 # ggplot needs a group to work with
county_map$value <- sapply(1:nrow(county_map),
function(x) round(runif(1, 1, 8), 0)) # for colours
ggplot(county_map, aes(x = long, y = lat, group = group)) +
geom_polygon(aes(fill = value)) +
coord_map() +
geom_point(data = pointData, aes(x = long, y = lat), shape = 21, fill = "red")
Which gives the following (note the points).
However, as to whether you should use geom_map
or geom_polygon
, I have not really thought about the issue much. Maybe somebody else has a view.
This works for me :
map1 <- ggplot(countyData) +
geom_map( map = county_map, aes(map_id = id,fill = value),
colour = "black") + coord_map() +
expand_limits(x = county_map$long, y = county_map$lat)
map1 + geom_point(mapping = aes(xx, yy), data = pointData)
For me geom_map
is a wrapper of a geom_polygon
. It is a layer that contains all geographical settings (lat and long grouped by id).
I would use geom_map
when I plot a map and geom_polygon
to plot any polygon type.
EDIT To add the map
来源:https://stackoverflow.com/questions/14698616/when-should-i-use-geom-map