Reputation: 25194
There are questions out there about the fact that ggplot2
can't plot polygon shapes that have holes.
That is because, if the order of points is not OK, the end graph looks bad, usually with clipping/trimming lines inside the donut shape.
I have read a lot about how order matters, but I am not able to step forward.
I have a SpatialPolygonsDataFrame
with 26 features (comes from raster::rasterToPolygons(dissolve=T)
) and I want to plot it with ggplot
.
Here's what happens -
r3.pol <- rasterToPolygons(r3, dissolve=T)
r3.df <- fortify(r3.pol)
names(r3.df) <- c('x','y','order','hole','piece','ID','group')
p <- ggplot(r3.df)
p <- p + geom_polygon(mapping=aes(x=x,y=y,group=ID), fill='red')
p <- p + coord_equal()
I see this output:
While it should be like so, with plot(r3.pol)
:
How can I make this work?
I tried for hours but I am not able to reorder r3.df
.
Also, can the information in r3.df$hole
be helpful? It is returned by the function fortify
for points that are holes (I think).
Side question: how can I give you my r3.pol SpatialPolygonsDataFrame, so that you can try yourself? I remember seeing long, reproducible "dumps" of objects here, but I don't know how to do it.
I save
d the polygons data frame here. Was not able to save it using dput
, sorry. You can fetch it using load
.
Upvotes: 4
Views: 2271
Reputation: 814
I suggest to install the package "ggpolypath" and use geom_polypath instead of geom_polygon. Works for me.
Upvotes: 4
Reputation: 25194
My temporary solution is: @#$% polygons, and use the raster
package.
Namely:
r <- raster(x=extent(r3.pol), crs=crs(r3.pol)) # empty raster from r3.pol
res(r) <- 250 # set a decent resolution (depends on your extent)
r <- setValues(r, 1) # fill r with ones
r <- mask(r, r3.pol) # clip r with the shape polygons
And now plot it as you would do with any raster
with ggplot
. The rasterVis
package might come helpful here, but I'm not using it, so:
rdf <- data.frame(rasterToPoints(r))
p <- ggplot(rdf) + geom_raster(mapping=aes(x=x, y=y), fill='red')
p <- p + coord_equal()
And here it goes.
Alternatively, you can create the raster with rasterize
, so the raster will hold the polygons values (in my case, just an integer):
r <- raster(x=extent(r3.pol), crs=crs(r3.pol))
res(r) <- 250
r <- rasterize(r3.pol, r)
rdf <- data.frame(rasterToPoints(r))
p <- ggplot(rdf) + geom_raster(mapping=aes(x=x, y=y, fill=factor(layer)))
p <- p + coord_equal()
If someone comes up with a decent solution for geom_polygon
, probably involving re-ordering of the polygons data frame, I'll be glad to consider it.
Upvotes: 2