ggplot2: Divide Legend into Two Columns, Each with Its Own Title

前端 未结 6 627
谎友^
谎友^ 2020-11-27 16:55

I have these factors

require(ggplot2)
names(table(diamonds$cut))
# [1] \"Fair\"      \"Good\"      \"Very Good\" \"Premium\"   \"Ideal\" 

w

6条回答
  •  暖寄归人
    2020-11-27 17:36

    Using cowplot, you just need to construct the legends separately and then stitch things back together. It does require using scale_fill_manual to make sure that the colors match across the plots, and there is lots of room for fiddling with the legend positioning, etc.

    Save the colors to use (here, using RColorBrewer)

    cut_colors <-
      setNames(brewer.pal(5, "Set1")
               , levels(diamonds$cut))
    

    Make the base plot -- without a legend:

    full_plot <-
      ggplot(diamonds, aes(color, fill=cut)) + geom_bar() + 
      scale_fill_manual(values = cut_colors) +
      theme(legend.position="none")
    

    Make two separate plots, limited to the cuts within the grouping that we want. We are not planning to plot these; we are just going to use the legends that they generate. Note that I am using dplyr for ease of filtering, but that is not strictly necessary. If you are doing this for more than two groups, it may be worth the effort to use split and lapply to generate a list of the plots instead of doing each manually.

    for_first_legend <-
      diamonds %>%
      filter(cut %in% c("Fair", "Good")) %>%
      ggplot(aes(color, fill=cut)) + geom_bar() + 
      scale_fill_manual(values = cut_colors
                        , name = "First Group")
    
    
    for_second_legend <-
      diamonds %>%
      filter(cut %in% c("Very Good", "Premium", "Ideal")) %>%
      ggplot(aes(color, fill=cut)) + geom_bar() + 
      scale_fill_manual(values = cut_colors
                        , name = "Second Group")
    

    Finally, stitch the plot and the legends together using plot_grid. Note that I used theme_set(theme_minimal()) before running the plot to get the theme that I personally like.

    plot_grid(
      full_plot
      , plot_grid(
        get_legend(for_first_legend)
        , get_legend(for_second_legend)
        , nrow = 1
      )
      , nrow = 2
      , rel_heights = c(8,2)
    )
    

提交回复
热议问题