2
votes

I am creating choropleth maps of county level data with ggplot2. I want to highlight multiple-county regions. It is simple enough to overlay a path or polygon of a subset of the county map data, but this leaves "interior" path lines. Is there a way to combine these regions into one group or simply hide the interior lines?

require(ggplot2)
require(maps)
require(maptools)

va <- map_data("county", region="virginia")

ggplot(va, aes(long, lat)) + coord_map() + 
  geom_polygon(aes(group=group)) +
  geom_path(data=subset(va, subregion %in% c("patrick", "henry", "franklin",
    "pittsylvania")), aes(group=group), size=1, color="white")

http://i.imgur.com/cRzqX.png

EDIT: The above example isn't exactly what I want to do. The code below is more representative of the actual project. The actual maps will be even more detailed than this since they use census tract level data and have geocoded points on top.

va <- map_data("county", region="virginia")
cty <- data.frame(subregion=unique(va$subregion))
cty$stat <- sample.int(nrow(cty))
va <- merge(va, cty, by="subregion")

p <- ggplot(va, aes(long, lat)) + coord_map() + 
  geom_polygon(aes(group=group, fill=stat), color="grey") +
  geom_path(data=subset(va, subregion %in% c("patrick", "henry", "franklin",
    "pittsylvania")), aes(group=group), size=1, color="white")

enter image description here

3
maybe take some alphahull of the coordinates? - baptiste
thanks, @baptiste, for the suggestion. i (think i) figured out ahull from the alphahull package. the problem is that it includes points inside the region, even at high values of alpha. chull works better in this regard but lacks the roughness of ahull. - attitude_stool
I see, that's because some borders have only very few points to define them, therefore the alpha hull extends too far inside. - baptiste
plotting the points with(subset(va, subregion %in% c("patrick", "henry", "franklin", "pittsylvania")), plot(long, lat)) gives an other idea: identify and remove the points that are common between the subregions. - baptiste
brute force would be to split the boundaries with a given resolution (something like this might help), then apply the alphahull. - baptiste

3 Answers

1
votes

looking at ?map, you can simply do the following,

boundary <- map("county", regions=c("virginia.patrick", "virginia.henry", "virginia.franklin", "virginia.pittsylvania"), boundary=TRUE, interior=FALSE)

now, for some reason neither map_data nor ggplot2:::fortify.map seem to be happy with this, but it wouldn't be hard to extract the relevant part of fortify.map and get it in a format that pleases coord_map. If you do, I'd suggest that you file a bug report as it seems that ggplot2 should support those options of map.

4
votes

If I get you right, you just need to swap geom_path for geom_polygon to plot without internal lines:

ggplot(va, aes(long, lat)) + coord_map() + geom_polygon(aes(group=group)) + 
   geom_polygon(data=subset(va, subregion %in% c("patrick", "henry", "franklin",
   "pittsylvania")), aes(group=group), size=1, color="white",fill="white")

enter image description here

0
votes

You can identify and remove the points at the border between subregions,

d <- subset(va, subregion %in% c("patrick", "henry", "franklin", "pittsylvania"))
duplicates <- duplicated(d[, c("long","lat")]) |
              duplicated(d[, c("long","lat")], fromLast=TRUE)

d2 <- d[duplicates, ]
d3 <- d[!duplicates, ]
d3 <- arrange(d3, order , region, group )
ggplot(d, aes(long, lat)) + geom_polygon(aes(fill=subregion), col=NA) +
  geom_point(colour="black") +
  geom_point(data=d2, colour="red") +
  geom_path(data=d3, fill=NA, colour="blue", size=1.2)

not sure how to fix the winding order and this sort of thing...