How to put plots without any space using plot_grid?

无人久伴 提交于 2019-12-12 11:06:26

问题


I'm doing an arrangement of 2x2 plots. The plots share the same axis, so I want to put them together, e.g.

This code:

library(ggplot2)
library(cowplot)

Value <- seq(0,1000, by = 1000/10)
Index <- 0:10
DF <- data.frame(Index, Value)


plot <- ggplot(DF, aes(x = Index, y = Value)) +
  geom_line(linetype = 2) +
  theme(aspect.ratio = 0.5)

plot_grid(plot, plot, plot, plot, align = "hv", ncol = 2)

produces

But I'd like something like:

How can I achieve a similar result?


回答1:


I think this is a case for the ggarrange() function from the egg package. Doing this with plot_grid() would require endless fiddling and isn't worth it.

(The technical reason is that plot_grid() keeps the total area for each plot in the grid constant, but if some plots have an x axis and others don’t then they take up different areas. One could try to circumvent this by using the rel_heights argument but there’s no good way to calculate the correct values for rel_heights, so it would be trial and error. By contrast, ggarrange() separately looks at the plot panel and the surrounding elements and makes sure the plot panels have the same size.)

Here is the code using ggarrange():

Value <- seq(0,1000, by = 1000/10)
Index <- 0:10
DF <- data.frame(Index, Value)


pbase <- ggplot(DF, aes(x = Index, y = Value)) +
  geom_line(linetype = 2) +
  theme_bw()

ptopleft <- pbase +
  scale_x_continuous(position = "top") +
  theme(plot.margin = margin(5.5, 0, 0, 5.5),
        axis.title.x = element_blank(),
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank())

ptopright <- pbase +
  scale_y_continuous(position = "right") +
  scale_x_continuous(position = "top") +
  theme(plot.margin = margin(5.5, 5.5, 0, 0),
        axis.title.x = element_blank(),
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank())

pbottomleft <- pbase +
  theme(plot.margin = margin(0, 0, 5.5, 5.5))

pbottomright <- pbase +
  scale_y_continuous(position = "right") +
  theme(plot.margin = margin(0, 5.5, 5.5, 0))

library(egg)      
ggarrange(ptopleft, ptopright,
          pbottomleft, pbottomright,
          ncol = 2)

Two comments:

  1. To remove every last bit of space below the plot panel on the top plots, we need to move the x axis to the top, even though we're not showing it. This is a strange limitation of the theming mechanism. We can't fully get rid of just one axis.

  2. I'm not a big fan of shared axis titles, as in your example. I think each axis should have a title. If you want shared axis titles, why not use the faceting mechanism?




回答2:


You can set subtle plot.margin each plot, then grid.arrange and add labs.

library(ggplot2)
library(grid)
library(gridExtra)

Value <- seq(0,1000, by = 1000/10)
Index <- 0:10
DF <- data.frame(Index, Value)

plot1 <- ggplot(DF, aes(x = Index, y = Value)) +
  geom_line(linetype = 2) +
  theme_minimal() +
  theme(aspect.ratio = 0.5, 
    panel.border = element_rect(fill = NA),
    axis.text.x = element_blank(),
    axis.title = element_blank(),
    axis.ticks = element_blank(),
    plot.margin = unit(c(5.5, 5.8, -50, 5.5), "pt")) 

plot2 <- ggplot(DF, aes(x = Index, y = Value)) +
  geom_line(linetype = 2) +
  theme_minimal() +
  theme(aspect.ratio = 0.5, 
    panel.border = element_rect(fill = NA),
    axis.text.x = element_blank(),
    axis.title = element_blank(),
    axis.ticks = element_blank(),
    plot.margin = unit(c(5.5, 5.5, -50, 5.5), "pt")) +
  scale_y_continuous(position = "right")

plot3 <- ggplot(DF, aes(x = Index, y = Value)) +
  geom_line(linetype = 2) +
  theme_minimal() +
  theme(aspect.ratio = 0.5, 
    panel.border = element_rect(fill = NA),
    axis.title = element_blank(),
    axis.ticks = element_blank(),
    plot.margin = unit(c(-50, 5.8, -50, 5.5), "pt")) 

plot4 <- ggplot(DF, aes(x = Index, y = Value)) +
  geom_line(linetype = 2) +
  theme_minimal() +
  theme(aspect.ratio = 0.5, 
    panel.border = element_rect(fill = NA),
    axis.title = element_blank(),
    axis.ticks = element_blank(),
    plot.margin = unit(c(-50, 5.5, -50, 5.5), "pt")) +
  scale_y_continuous(position = "right")

grid.arrange(grobs = list(plot1, plot2, plot3, plot4), ncol = 2, bottom = 'Index', left = 'Value', right = 'Value')

final plot



来源:https://stackoverflow.com/questions/47614314/how-to-put-plots-without-any-space-using-plot-grid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!