Set margins between plots using multiplot

后端 未结 3 602
粉色の甜心
粉色の甜心 2021-01-23 04:50

To display multiple plots I use multiplot (http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2)/), now I have two plots who share the same x-axis range and are

相关标签:
3条回答
  • 2021-01-23 05:31

    To reduce space between the plots, remove the bottom margin of the top plot and remove the top margin of the bottom plot. The code below sets these margins to 0, which still results in a tiny bit of white space between the plots. You can make these margins slightly negative (maybe -0.1 or so) to completely remove the white space. Rather than the multiplot function, we use grid.arrange from the gridExtra package to lay out the plots. :

    library(grid)
    library(gridExtra)
    
    ## Create two sample plots with the same x axis using built-in mtcars data frame
    
    # Top plot: Remove bottom margin, x-labels, and x title
    p1 = ggplot(mtcars, aes(wt, mpg)) + geom_point() + 
      xlab(NULL) + 
      theme(axis.text.x=element_blank(),axis.ticks.x=element_blank(),
            plot.margin=unit(c(1,1,0,1), "lines"))
    
    # Bottom plot: Remove top margin
    p2 = ggplot(mtcars, aes(wt, carb)) + geom_point() +
      theme(plot.margin=unit(c(0,1,1,1), "lines"))
    
    # Lay out plots in one column
    grid.arrange(p1, p2, ncol=1) 
    

    Two problems with the above layout: (1) the y axes are not justified properly, and (2) the height of the lower plot's plot area is less than that of upper plot's plot area. The code below addresses these issues:

    # Left justify plots
    # Source: http://stackoverflow.com/a/13295880/496488
    gA <- ggplotGrob(p1)
    gB <- ggplotGrob(p2)
    
    maxWidth = grid::unit.pmax(gA$widths[2:5], gB$widths[2:5])
    gA$widths[2:5] <- as.list(maxWidth)
    gB$widths[2:5] <- as.list(maxWidth)
    
    # Lay out justified plots. Use heights argument to equalize heights of each plot area
    grid.arrange(gA, gB, heights=c(0.47,0.53), ncol=1)
    

    You can exactly equalize the heights of each plot area using the same trick as we used to left-justify the plots (rather than doing it by eye using the heights argument to grid.arrange), but then the plot margins get added back. I'm not sure of how to deal with that, but here's the code for reference:

    maxHeight = grid::unit.pmax(gA$heights[2:5], gB$heights[2:5])
    gA$heights[2:5] <- as.list(maxHeight)
    gB$heights[2:5] <- as.list(maxHeight)
    
    0 讨论(0)
  • 2021-01-23 05:34

    The last update of ggplot2 gives much more control over the plot. See for example:

    ggplot(mtcars, aes(disp, mpg)) +
         geom_point() +
         facet_wrap(~vs)
    

    You can further adjust the labels, number of rows, and how scales will be displayed, for instance: nrow = 2; scales = "free".

    0 讨论(0)
  • 2021-01-23 05:38

    It is easier than you might think to re-arrange the data so that you can take advantage of the nice alignment features that already exist in ggplot2. See below for an example replicating eipi10's answer, but without having to use ggplotGrob.

    What you have to do is just select the columns you want to plot, along with the ID columns (in this case, the car model and the x-axis value column). Then melt, and it's ready to plot using the standard facet procedure.

    Note that the "switch" option in the facet_grid call is a new feature that you can access by updating to the most recent CRAN version. I used that to replace the regular y-axis title, which was omitted using theme.

    The nice part about this approach is that the plots will always be perfectly aligned.

    library("ggplot2")
    library("dplyr")
    library("reshape2")
    
    df <- mtcars %>% 
      add_rownames(var = "Model") %>%
      select(Model, wt, mpg, carb) %>%
      melt(id.vars = c("Model","wt"))
    
    ggplot(df)+
      aes(x=wt, y=value)+
      geom_point()+
      theme(strip.background=element_blank())+
      facet_grid(variable ~ ., scales="free_y", switch="y")
    

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