Search code examples
rggplot2cowplot

move inset plot legend


I have an inset plot with a legend that I want to be shown at the bottom of the overall figure. This legend isn't the same for the larger plot, since I added more layers to the inset plot. How can I plot just the legend of the inset plot at the bottom of the entire figure?

Code below:

path.eez.usa <- ("~/Downloads/EEZ_land_union_v3_202003/")
fnam.eez.usa <- "EEZ_Land_v3_202030.shp"
eez.usa <- st_read(dsn = path.eez.usa, layer = file_path_sans_ext(fnam.eez.usa))

dat.eez.usa1 <- fortify(eez.usa) # a 180400x22 dataframe
world <- ne_countries(scale = "medium", returnclass = "sf")


bigger_plot <- ggplot()+
  geom_sf(data = world)+
  borders("state") +
  scale_x_continuous(breaks = c(seq(from = -140, to = -114, by = 5))) +
  scale_y_continuous(breaks = c(seq(from = 29, to = 50, by = 2))) +
  coord_sf(xlim = c(-113, -140), ylim = c(29, 50.5), expand = FALSE)+
  theme(strip.background = element_blank(), 
        legend.position = 'bottom', 
        strip.text.x = element_text(
          size = 12, hjust = 0, face = "bold"),
        axis.title.x=element_blank(),
        axis.title.y=element_blank())



inset <- ggplot() +
  geom_sf(data = dat.eez.usa1, size = 1.5, aes(color = "eez"), fill = 'transparent')+
  scale_color_manual(name = "", 
                     values = c(eez = "lightblue"), 
                     labels = c('EEZ')) +
  coord_sf(xlim = c(-117, -121.5), ylim = c(31.75, 36), expand = FALSE)+
  scale_x_continuous(breaks = c(seq(from = -121, to = -117, by = 2))) +
  scale_y_continuous(breaks = c(seq(from = 32, to = 36, by = 2)))+
  theme(
        strip.background = element_blank(), 
        strip.text.x = element_text(
          size = 12, hjust = 0, face = "bold"),
        panel.border = element_rect(color = "red", 
                                    fill = NA, 
                                    linewidth = 1),
        axis.line.y = element_blank(), axis.line.x = element_blank(),
        axis.title.x=element_blank(),
        axis.title.y=element_blank(),
        axis.text.x = element_text(size = 6),
        axis.text.y = element_text(size = 6),
        legend.location = 'plot')


p2 <- ggdraw(bigger_plot) +
  draw_plot(inset,
            x = .086, 
            y = 0.15,
            width = 0.45, 
            height = 0.45)

Solution

  • One option would be to add a legend to your main plot for which I use a fake invisible geom_point and remove the legend for your inset plot.

    As I don't have your dataset dat.eez.usa1 I simply used the world dataset for the inset plot, too.

    library(rnaturalearth)
    library(ggplot2)
    library(cowplot)
    
    world <- ne_countries(scale = "medium", returnclass = "sf")
    
    bigger_plot <- ggplot() +
      geom_sf(data = world) +
      borders("state") +
      scale_x_continuous(breaks = c(seq(from = -140, to = -114, by = 5))) +
      scale_y_continuous(breaks = c(seq(from = 29, to = 50, by = 2))) +
      coord_sf(xlim = c(-113, -140), ylim = c(29, 50.5), expand = FALSE) +
      theme(
        strip.background = element_blank(),
        legend.position = "bottom",
        strip.text.x = element_text(
          size = 12, hjust = 0, face = "bold"
        ),
        axis.title.x = element_blank(),
        axis.title.y = element_blank()
      ) +
      # Add color legend using an invisible geom_point
      geom_point(
        data = data.frame(color = 1),
        aes(color = "eez"), x = NA, y = NA, na.rm = TRUE,
        key_glyph = "polygon"
      ) +
      scale_color_manual(
        name = "",
        values = c(eez = "lightblue"),
        labels = c("EEZ")
      )  
    
    inset <- ggplot() +
      geom_sf(data = world, size = 1.5, aes(color = "eez"), fill = "transparent") +
      scale_color_manual(
        name = "",
        values = c(eez = "lightblue"),
        labels = c("EEZ"),
        guide = "none"
      ) +
      coord_sf(xlim = c(-117, -121.5), ylim = c(31.75, 36), expand = FALSE) +
      scale_x_continuous(breaks = c(seq(from = -121, to = -117, by = 2))) +
      scale_y_continuous(breaks = c(seq(from = 32, to = 36, by = 2))) +
      theme(
        strip.background = element_blank(),
        strip.text.x = element_text(
          size = 12, hjust = 0, face = "bold"
        ),
        panel.border = element_rect(
          color = "red",
          fill = NA,
          linewidth = 1
        ),
        axis.line.y = element_blank(), axis.line.x = element_blank(),
        axis.title.x = element_blank(),
        axis.title.y = element_blank(),
        axis.text.x = element_text(size = 6),
        axis.text.y = element_text(size = 6),
        legend.location = "plot"
      )
    
    
    p2 <- ggdraw(bigger_plot) +
      draw_plot(inset,
        x = .086,
        y = 0.15,
        width = 0.45,
        height = 0.45
      )
    
    p2