Align multiple plots in ggplot2 when some have legends and others don't

前端 未结 6 1461
离开以前
离开以前 2020-11-30 03:09

I have used the method indicated here to align graphs sharing the same abscissa.

But I can\'t make it work when some of my graphs have a legend and others don\'t.

6条回答
  •  盖世英雄少女心
    2020-11-30 03:45

    Expanding on @Axeman's answer, you can do all of this with cowplot without ever needing to use draw_plot directly. Essentially, you just make the plot in two columns -- one for the plots themselves and one for the legends -- and then place them next to each other. Note that, because g2 has no legend, I am using an empty ggplot object to hold the place of that legend in the legends column.

    library(cowplot)
    
    theme_set(theme_minimal())
    
    plot_grid(
      plot_grid(
        g1 + theme(legend.position = "none")
        , g2
        , g3 + theme(legend.position = "none")
        , ncol = 1
        , align = "hv")
      , plot_grid(
        get_legend(g1)
        , ggplot()
        , get_legend(g3)
        , ncol =1)
      , rel_widths = c(7,3)
      )
    

    Gives

    The main advantage here, in my mind, is the ability to set and skip legends as needed for each of the subplots.

    Of note is that, if all of the plots have a legend, plot_grid handles the alignment for you:

    plot_grid(
      g1
      , g3
      , align = "hv"
      , ncol = 1
    )
    

    gives

    It is only the missing legend in g2 that causes problems.

    Therefore, if you add a dummy legend to g2 and hide it's elements, you can get plot_grid to do all of the alignment for you, instead of worrying about manually adjusting rel_widths if you change the size of the output

    plot_grid(
      g1
      , g2 + 
          geom_line(aes(color = "Test")) +
          scale_color_manual(values = NA) +
          theme(legend.text = element_blank()
                , legend.title = element_blank())
      , g3
      , align = "hv"
      , ncol = 1
    )
    

    gives

    This also means that you can easily have more than one column, but still keep the plot areas the same. Simply removing , ncol = 1 from above yields a plot with 2 columns, but still correctly spaced (though you'll need to adjust the aspect ratio to make it useable):

    As @baptiste suggested, you can also move the legends over so that they are all aligned to the left of in the "legend" portion of the plot by adding theme(legend.justification = "left") to the plots with the legends (or in theme_set to set globally), like this:

    plot_grid(
      g1 +
        theme(legend.justification = "left")
      , 
      g2 + 
        geom_line(aes(color = "Test")) +
        scale_color_manual(values = NA) +
        theme(legend.text = element_blank()
              , legend.title = element_blank())
      , g3 +
        theme(legend.justification = "left")
      , align = "hv"
      , ncol = 1
    )
    

    gives

提交回复
热议问题