How do I add a legend using aes, ggplot2 and maps?

1.4k Views Asked by At

I'm trying to make a map with points plotted for the Canadian prairie provinces, but I'm having no luck adding in a legend to my map. I'm very new to mapping in r, so I'm not understanding how I should include aes to get a legend. My data for siteDataTrees is from an excel csv file and the top looks like this: siteDataTrees and the data for siteDataBoth is also from a csv file and the top looks like this: siteDataBoth.

Here's what I have so far for my code:

library(maps)
library(ggplot2)
library(sf)

prairies1 <- map("worldHires","Canada", xlim = c(-120,-87), ylim = c(49,61),
             plot = FALSE, fill = TRUE)
prairies <- st_as_sf(prairies1)

ggplot(data = prairies) +  
    geom_sf() +
    geom_point(data = siteDataTrees, aes(x = long, y = lat), size = 2.5, pch = 21, 
     fill = "purple", show.legend = TRUE) +
    geom_point(data = siteDataBoth, aes(x = long, y = lat), size = 2.5, pch = 21, 
     fill = "light green", show.legend = TRUE) +
    geom_text(data = locations, aes(x = long, y = lat, label = name), 
            size = 2, col = "black", check_overlap = FALSE) +
    annotation_scale(location = "tr", width_hint = 0.2) +
    ggtitle("Climate Stations and Tree Chronology Locations for South AB") +
    labs(x = "latitude", y = "longitude") +
    theme(legend.position = "right") + 
    coord_sf(xlim = c(-115, -110), ylim = c(48.9, 50.49), expand = FALSE)

I've also included a map to show what it looks like without the legend.
Map
How should I take the data frame prairies and use it with aes to include a legend? Is there another way to add in a legend in ggplot2 without using the aes function? Thank you in advance for your help and please let me know if something is missing as this is my first posting

1

There are 1 best solutions below

1
davidnortes On

Let me give you a couple of examples on how to work out a legend using a slightly modified example from r-spatial.

First we prepare the data:

library(maps)
library(ggplot2)
library(sf)
library(rnaturalearth)
library(rnaturalearthdata)

world <- ne_countries(scale = "medium", returnclass = "sf")
(sites <- data.frame(longitude = c(-80.144005, -80.109), 
                     latitude = c(26.479005,26.83), 
                     type = c("tree", "station")))

Now we plot. Case 1: color is not an issue

ggplot(data = world) +
  geom_sf() +
  geom_point(data = sites, 
             aes(x = longitude, y = latitude, fill = type), 
             size = 4, 
             shape = 23) +
  coord_sf(xlim = c(-88, -78), ylim = c(24.5, 33), expand = FALSE) +
  theme(legend.position = "bottom")

enter image description here

Case 2: fill color is an issue. Here we can use a named vectors to pass the colors and the labels we want by type of point. For example:

mapfill <- c('tree' = "forestgreen", 'station' = "purple")
maplab <- c('tree' = "trees in prairies", 'station' = "Stations in prairies")

Then we plot combining both mapfill and maplab:

ggplot(data = world) +
  geom_sf() +
  geom_point(data = sites, aes(x = longitude, y = latitude, fill = type), size = 4, 
             shape = 23) +
  scale_fill_manual(values = mapfill, labels = maplab) +
  coord_sf(xlim = c(-88, -78), ylim = c(24.5, 33), expand = FALSE) +
  theme(legend.position = "bottom")

enter image description here

Remark 1 If you do not want type in the legend title you can either delete it using legend. title = element_blank() within theme

Remark 2 If, instead of fill, you are using color, use function scale_color_manual. If you are combining both fill and color do the same with scale_***_manual

In spirit of full disclosure, if you do not mind the colors and you want a quick fix (and I cannot stress this enough) you can also code fill = "TextYouWantInLegend" within aes. See following example:

ggplot(data = world) +
  geom_sf() +
  geom_point(data = sites[1,], aes(x = longitude, y = latitude, fill = "toto"), size = 4, 
             shape = 23) +
  geom_point(data = sites[2,], aes(x = longitude, y = latitude, fill = "koko"), size = 4, 
             shape = 23) +
  coord_sf(xlim = c(-88, -78), ylim = c(24.5, 33), expand = FALSE) +
  theme(legend.position = "bottom")

enter image description here