How to use several symbols, colour, and fill in ggmap without changing the legend colour in R?

Viewed 728

I'm using ggmap to plot some filled points across the ocean but they overlap so I used colour=black to give them an outline. When I use pch=21 the legend doesn't change and the points are outlined in black like I want. But, I am trying to get 3 different symbols on the map as well. When I specify the different symbols my points in the legend all turn black.

Here is some sample data and the code I used to get the map with the correct legend but wrong symbols

#library
library(ggmap)
library(mapdata)
library(ggplot2)

#sample

mapoc_temp = data.frame(longitude= c(-64.5, -63.1, -62.4, -62.2, -66.0, -61.9), 
                                    latitude= c(42.7, 44.8, 45.8, 45.6, 43.0, 40.2),
                                    Zone = sample(c(1,4,6,7), 6, replace = T),
                                    location = sample(c(1,2,3), 6, replace = T))

#map
canada = map_data("worldHires")
ggplot(data = canada) +
  borders("world", xlim = c(-130, -60), ylim = c(20, 50), colour = "black", fill = "grey50") +
  geom_polygon(data = canada, aes(x=long, y = lat, group = group), fill = "grey50") +
  #coordinates of my map
  coord_sf(xlim=c(-84, -41), ylim=c(24,51), expand = FALSE) +
  #map the receiver locations
  geom_point(data = mapoc_temp,
             mapping = aes(x = longitude, 
                           y = latitude,
                           fill = Zone), 
             pch = 21,
             size = 15, colour = "black") +
  #fill the zones 
  scale_color_manual(values=c("#01579B", "#4FC3F7", "#ffa600", "#ff6361")) +
  scale_fill_manual(values=c("#01579B", "#4FC3F7", "#ffa600", "#ff6361")) 

and this is what the map looks like enter image description here

When I try to add the symbols, I get the correct symbols but my legend isn't correct anymore. Below is the code and image.

ggplot(data = canada) +
  borders("world", xlim = c(-130, -60), ylim = c(20, 50), colour = "black", fill = "grey50") +
  geom_polygon(data = canada, aes(x=long, y = lat, group = group), fill = "grey50") +
  #coordinates of my map
  coord_sf(xlim=c(-84, -41), ylim=c(24,51), expand = FALSE) +
  #map the receiver locations
  geom_point(data = mapoc_temp,
             mapping = aes(x = longitude, 
                           y = latitude,
                           fill = as.factor(Zone)), 
             pch = pch = if_else(mapoc_temp$location == 1,25,
                                 if_else(mapoc_temp$location == 3, 23, 21)),
             size = 15, colour = "black") +
  scale_x_continuous(label = abs) +
  scale_y_continuous(label = abs) +
  #fill the zones in with viridis
  scale_color_manual(values=c("#01579B", "#4FC3F7", "#ffa600", "#ff6361")) +
  scale_fill_manual(values=c("#01579B", "#4FC3F7", "#ffa600", "#ff6361")) 

enter image description here

Does anyone know how to fix the legend in the second image so that the points are the correct colours? I don't need the symbols to be in the legend

2 Answers

Actually, your issue is due to a bug described here: https://github.com/tidyverse/ggplot2/issues/2322.

To go over, you can do:

ggplot(data = canada) +
  borders("world", xlim = c(-130, -60), ylim = c(20, 50), colour = "black", fill = "grey50") +
  geom_polygon(data = canada, aes(x=long, y = lat, group = group), fill = "grey50") +
  #coordinates of my map
  coord_sf(xlim=c(-84, -41), ylim=c(24,51), expand = FALSE) +
  #map the receiver locations
  geom_point(inherit.aes = FALSE, data = mapoc_temp,
             mapping = aes(x = longitude, 
                           y = latitude,
                           fill = factor(Zone),
                           shape = factor(location)),
             size = 5) +
  scale_x_continuous(label = abs) +
  scale_y_continuous(label = abs) +
  #fill the zones in with viridis
  scale_fill_manual(name = "Zone", values=c("#01579B", "#4FC3F7", "#ffa600", "#ff6361"), breaks = c("1","4","6","7")) +
  scale_shape_manual(values = c("1" = 21, "2" = 22, "3" = 24))+
  guides(fill = guide_legend(override.aes=list(shape=21)), shape = FALSE)

enter image description here

As mentioned by @Edward, you can get rid of the shape legend by adding guides(shape = FALSE).

Does it answer your question ?

I don't have your data, so I will use the good ol' mtcars dataset. The trick is to assign the shapes manually, otherwise, ggplot will complain "A continuous variable can not be mapped to shape".

mtcars$shape <- ifelse(mtcars$cyl==4, 21, ifelse(mtcars$cyl==6, 23, 25))

ggplot(mtcars, aes(wt, mpg)) + 
   geom_point(aes(fill = factor(cyl), shape=factor(cyl)), col="black", size=3) +
   scale_shape_manual(values=c(21,23,25))

enter image description here


For your own data, try:

mapoc_temp$shape <- factor(mapoc_temp$location + 20)

geom_point(data = mapoc_temp,
           mapping = aes(x = longitude, 
                         y = latitude,
                         fill = factor(Zone),
                         shape= shape),
           size = 15, colour = "black") +
  scale_shape_manual(values=c(21,22,23)) + # Must be same length as unique location.
  guides(shape=FALSE) + # If you don't want an extra shape legend.
  guides(fill = guide_legend(override.aes=list(shape=21))) # A necessary fudge
Related