Edited as a response to @hrbrmstr's great answer:
I'm mapping 2 groups of countries and would like a legend to go with it. Since I'm using my own data, it's hard to provide a MRE. In my previous code I was using geom_polygon
to plot the shapes (read from a shapefile) because fortify
throws away the additional data the associated dataframe:
ggplot() + aes(long, lat, group = group) + theme_bw() +
scale_x_continuous(limits = c(-15, 35)) +
scale_y_continuous(limits = c(25, 75)) +
scale_fill_manual("Affected?", labels = c("Yes", "No"),
values = c("gray10", "gray80")) +
geom_polygon(data = affected.countries, fill = "gray10", color = "black") +
geom_polygon(data = unaffected.countries, fill = "gray80", color = "black")
The result:
Now I've tried taking a page from @hrbrmstr's playbook. Because fortify
throws away my other columns, I made 2 subsets of my original data, which is of class SpatialPolygonsDataFrame
. I fortify
them and given them a dummy variable that shows what I need and then try to plot them using the boolean column to control the fill:
affected.countries <- fortify(affected.countries)
affected.countries$affected <- T
unaffected.countries <- fortify(unaffected.countries)
unaffected.countries$affected <- F
# all.countries now contains column affected
all.countries <- rbind(affected.countries, unaffected.countries)
gg <- ggplot() + coord_map(xlim = c(-13, 35), ylim = c(32, 71)) + theme_bw()
# Base map
gg <- gg + geom_map(data = all.countries, map = all.countries,
aes(x = long, y = lat, map_id = id),
fill = NA, color="gray10")
# Base map looks OK
gg
# Add filled data
gg <- gg + geom_map(data = all.countries, map = all.countries,
aes(fill = affected, map_id = id),
fill="gray10")
# For some reason, everything is filled!
gg <- gg + scale_fill_manual("Affected?", labels = c("No", "Yes"),
values = c("gray80", "gray10"))
# And the legend isn't shown
gg
For these results:
I thought the problem was that my fill
argument wasn't in aes
, but here it is. Sadly, I don't see a way of using a second dataframe as in @hrbrmstr's answer, since I don't have the appropriate columns in my data, but I thought the boolean column would solve it. And although I could do it by hacking the code from the answer, I'd prefer my own country boundaries.
Notably, if I include the fill
argument outside the aes
but inside the geom_polygon
call, the fill works correctly, but the legend isn't shown. If I specify the color in aes
, a seemingly random color is shown.
What principle am I missing? Thanks again!