I'm trying to build a map in ggplot2
using data from separate data frames.
library(maptools) xx <- readShapePoly(system.file("shapes/sids.shp", package="maptools")[1], IDvar="FIPSNO", proj4string=CRS("+proj=longlat +ellps=clrk66")) xx.sub1 <- subset(xx, xx$FIPSNO < 37010) xx.sub2 <- subset(xx, xx$FIPSNO > 37010) xx.sub1@data$id <- rownames(xx.sub1@data) xx.sub1.points <- fortify(xx.sub1, region="id") xx.sub1.df = plyr::join(xx.sub1.points, xx.sub1@data, by="id") xx.sub2@data$id <- rownames(xx.sub2@data) xx.sub2.points <- fortify(xx.sub2, region="id") xx.sub2.df = plyr::join(xx.sub2.points, xx.sub2@data, by="id") ggplot(xx.sub2.df) + aes(long, lat, fill = (SID79/BIR79)*1000, group = group) + geom_polygon() + geom_path(color="grey80") + coord_equal() + scale_fill_gradientn(colours = RColorBrewer::brewer.pal(7, "YlOrBr")) + geom_polygon(data = xx.sub1.df, fill = "grey50") + geom_path(data = xx.sub1.df, color="grey80") + labs(fill = "Mapped value", title = "Title")
Up to this point everything works as expected and I get a nice map:
What I'd like to change however is to add separate legend for data from xx.sub1.df
- since all polygons are just filled with grey I hope it will be one additional entry.
How can I achieve that?
You can place the legend literally anywhere. To put it around the chart, use the legend. position option and specify top , right , bottom , or left . To put it inside the plot area, specify a vector of length 2, both values going between 0 and 1 and giving the x and y coordinates.
You can use the following syntax to change the legend labels in ggplot2: p + scale_fill_discrete(labels=c('label1', 'label2', 'label3', ...))
To change the color legend element border using ggplot2, we can use theme function where can put color in legend. key argument to desired color with element_rect.
I'm not 100% sure this is what you want, but here's how I'd approach the problem as I understand it. If we map some unused geom
with any data from xx.sub1.df
, but make it invisible on the plot, we can still get a legend for that geom
. Here I've used geom_point
, but you could make it others.
p <- ggplot(xx.sub2.df) + aes(long, lat, fill = (SID79/BIR79)*1000, group = group) + geom_polygon() + geom_path(color="grey80") + coord_equal() + scale_fill_gradientn(colours = brewer.pal(7, "YlOrBr")) + geom_polygon(data = xx.sub1.df, fill = "grey50") + geom_path(data = xx.sub1.df, color="grey80") + labs(fill = "Mapped value", title = "Title") #Now we add geom_point() setting shape as NA, but the colour as "grey50", so the #legend will be displaying the right colour p2 <- p + geom_point(data = xx.sub1.df, aes(size="xx.sub1", shape = NA), colour = "grey50")
Now we just need to alter the size and shape of the point on the legend, and change the name of the legend (thanks to @DizisElferts who demonstrated this earlier).
p2 + guides(size=guide_legend("Source", override.aes=list(shape=15, size = 10)))
Of course you can change the way the labels work or whatever to highlight what you want to show.
If this isn't what you're after, let me know!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With