ggplot - Multiple legends arrangement

后端 未结 1 1596
说谎
说谎 2020-12-06 06:04

I want to arrange mutiple legend in ggplot with multiple rows and columns. However currently, from the documentation I can only decide there direction or manipulate rows/col

相关标签:
1条回答
  • 2020-12-06 06:46

    The idea is to create each plot individually (color, fill & size) then extract their legends and combine them in a desired way together with the main plot.

    See more about the cowplot package here & the patchwork package here

    library(ggplot2)
    library(cowplot)   # get_legend() & plot_grid() functions
    library(patchwork) # blank plot: plot_spacer()
    
    data <- seq(1000, 4000, by = 1000)
    colorScales <- c("#c43b3b", "#80c43b", "#3bc4c4", "#7f3bc4")
    names(colorScales) <- data
    
    # Original plot without legend
    p0 <- ggplot() +
      geom_point(aes(x = data, y = data, 
                     color = as.character(data), fill = data, size = data),
                 shape = 21
      ) +
      scale_color_manual(
        name = "Legend 1",
        values = colorScales
      ) +
      scale_fill_gradientn(
        name = "Legend 2",
        limits = c(0, max(data)),
        colours = rev(c("#000000", "#FFFFFF", "#BA0000")),
        values = c(0, 0.5, 1)
      ) +
      scale_size_continuous(name = "Legend 3") +
      theme(legend.direction = "vertical", legend.box = "horizontal") +
      theme(legend.position = "none")
    
    # color only
    p1 <- ggplot() +
      geom_point(aes(x = data, y = data, color = as.character(data)),
                 shape = 21
      ) +
      scale_color_manual(
        name = "Legend 1",
        values = colorScales
      ) +
      theme(legend.direction = "vertical", legend.box = "vertical")
    
    # fill only
    p2 <- ggplot() +
      geom_point(aes(x = data, y = data, fill = data),
                 shape = 21
      ) +
      scale_fill_gradientn(
        name = "Legend 2",
        limits = c(0, max(data)),
        colours = rev(c("#000000", "#FFFFFF", "#BA0000")),
        values = c(0, 0.5, 1)
      ) +
      theme(legend.direction = "vertical", legend.box = "vertical")
    
    # size only
    p3 <- ggplot() +
      geom_point(aes(x = data, y = data, size = data),
                 shape = 21
      ) +
      scale_size_continuous(name = "Legend 3") +
      theme(legend.direction = "vertical", legend.box = "vertical")
    

    Get all legends

    leg1 <- get_legend(p1)
    leg2 <- get_legend(p2)
    leg3 <- get_legend(p3)
    
    # create a blank plot for legend alignment 
    blank_p <- plot_spacer() + theme_void()
    

    Combine legends

    # combine legend 1 & 2
    leg12 <- plot_grid(leg1, leg2,
                       blank_p,
                       nrow = 3
    )
    
    # combine legend 3 & blank plot
    leg30 <- plot_grid(leg3, blank_p,
                       blank_p, 
                       nrow = 3
    )
    
    # combine all legends
    leg123 <- plot_grid(leg12, leg30,
                        ncol = 2
    )
    

    Put everything together

    final_p <- plot_grid(p0,
                         leg123,
                         nrow = 1,
                         align = "h",
                         axis = "t",
                         rel_widths = c(1, 0.3)
    )
    
    print(final_p)
    

    Created on 2018-08-28 by the reprex package (v0.2.0.9000).

    0 讨论(0)
提交回复
热议问题