Reputation: 23630
I'm having difficulty getting ggplot to plot polygons that feature holes. The following demonstrates. First get the shapefile with git clone https://github.com/geotheory/volcano
. Next:
require(ggplot2); require(ggmap); require(dplyr); require(maptools)
v = readShapePoly('volcano/volcano.shp')
v@proj4string = CRS('+proj=longlat +datum=WGS84')
# confirm polygons spatially exclusive (don't overlap)
plot(t(bbox(v)), type='l', lwd=8)
plot(v, col=paste0(colorRampPalette(c('grey','red'))(8),'dd'), add=T)
Looks ok. A dd
alpha should render the line invisible if obscured by multiple polygons. Now let's try in ggplot.
d = fortify(v) %>% as_data_frame()
bb = bbox(v)
toner = get_stamenmap(c(bb[1,1], bb[2,1], bb[1,2], bb[2,2]), zoom=11, maptype='toner')
ggmap(toner) + geom_polygon(data=d, aes(long, lat, group=group, fill=id), alpha=.5)
Central polygons must be overlapping since the underlying map is completely obscured in the centre. Let's check the fortified data for holes:
d %>% select(id, hole) %>% table()
hole
id FALSE TRUE
0 278 0
1 715 0
2 392 388
3 388 331
4 390 265
5 265 387
6 328 125
7 125 0
Looks ok, so let's try visualising them individually.
i = 3
plot(v[i,], col='red')
ggplot(filter(d, id == i-1)) + geom_polygon(aes(long, lat, group=group, col=hole), fill=NA)
ggplot() + geom_polygon(data=filter(d, id==i-1), aes(long,lat, group=group))
Something appears to be going wrong. ggplot seems to be ignoring the holes. Unless it's a problem with the shapefile. Any suggestions how to diagnose/fix this?
Upvotes: 6
Views: 1044
Reputation: 6776
"hadley/ggplot2: plotting polygon shapefiles" says "..., the hole state is retained, but this information is not used by ggplot2". Fortunately, ggspatial
package, "Fish & Whistle: Holes in ggplot polygons" taught me, seem to solve some problems, such as the overlapping problem. (The white area upper the label of "Biggin Hill" isn't due to ggspatial
package because it is also on ggplot(d) + geom_polygon(aes(long, lat, group = group, fill = id))
on my env)
devtools::install_github("paleolimbot/ggspatial")
library(ggspatial)
ggmap(toner) + geom_spatial(data=v, aes(fill=id), alpha=.8)
Upvotes: 4
Reputation: 1500
I have the same problem on world map with the country Lesotho. Normally, ggplot2 should detect hole, because the sens of the polygone is reverse (anticlokwise instead of clockwise if I remember).
Here the solution seems to drop the hole from the selection.
colorsbrewer_red <- c( "#fff5f0","#fee0d2", "#fcbba1","#fc9272", "#fb6a4a", "#ef3b2c", "#cb181d", "#99000d")
ggmap(toner) +
geom_polygon(data=d[!d$hole,], aes(long, lat, group=group, fill=id), alpha=.5) +
scale_fill_manual(name = "",
values= colorsbrewer_red,
na.value = "# 808080",
drop=FALSE)
Anyway, if someone know how to deal directly with hole in geom_polygon
, It would be great.
Upvotes: 1