0

I have been using the code below to create 3 separate plots and then using ggarrange in the ggpubr package to combine them into one plot and saving it as an image. However, once I created an Rmd of my script this function is very temperamental and gives me the error "Faceting variables must have at least one value" even when it runs fine outside of the Rmd. Is there a different way to get the same results using something in the ggplot2 package? or another simpler way? Edit: I would like to maintain the girds in my graph and not use a complex way to get a common legend that cowplot requires.

graph_1 <- ggplot(subset(data_p, Target == "1"), aes(x=as.integer(volume), y=percent_yield, color=Tech.Rep))+
  geom_point()+
  geom_smooth(se=FALSE)+
  facet_wrap(~sample)+
  ggtitle(paste("Graph 1"))+
  ylab("PERCENT YIELD")+
  scale_x_discrete(limits= levels(data_p$volume))+
  ylim(min=-150, max=150)+
  theme(axis.text.x=element_text(size=10,angle=85,hjust=1,vjust=1))+
  theme(legend.position="none")+
  geom_ribbon(aes(ymax=100, ymin=50), alpha = 0.2, fill="green", col="green")+
  geom_ribbon(aes(ymax=0, ymin=0), alpha = 0.2, fill="black", col="black", size=1.0)

graph_2 <- ggplot(subset(data_p, Target == "2"), aes(x=as.integer(volume), y=percent_yield, color=Tech.Rep))+
  geom_point()+
  geom_smooth(se=FALSE)+
  facet_wrap(~sample)+
  ggtitle(paste("Graph 2"))+
  ylab("PERCENT YIELD")+
  scale_x_discrete(limits= levels(data_p$volume))+
  ylim(min=-150, max=150)+
  theme(axis.text.x=element_text(size=10,angle=85,hjust=1,vjust=1))+
  theme(legend.position="none")+
  geom_ribbon(aes(ymax=100, ymin=50), alpha = 0.2, fill="green", col="green")+
  geom_ribbon(aes(ymax=0, ymin=0), alpha = 0.2, fill="black", col="black", size=1.0)


graph_3 <- ggplot(subset(data_p, Target == "3"), aes(x=as.integer(volume), y=percent_yield, color=Tech.Rep))+
  geom_point()+
  geom_smooth(se=FALSE)+
  facet_wrap(~sample)+
  ggtitle(paste("Graph 3"))+
  ylab("PERCENT YIELD")+
  scale_x_discrete(limits= levels(data_p$volume))+
  ylim(min=-150, max=150)+
  theme(axis.text.x=element_text(size=10,angle=85,hjust=1,vjust=1))+
  theme(legend.position="none")+
  geom_ribbon(aes(ymax=100, ymin=50), alpha = 0.2, fill="green", col="green")+
  geom_ribbon(aes(ymax=0, ymin=0), alpha = 0.2, fill="black", col="black", size=1.0)

ggarrange(graph_1, graph_2, graph_3, ncol=3, nrow=1, common.legend=TRUE, legend= "bottom")

Here is an example of what a single plot would look like: enter image description here

and here is what the combined plots look like:

enter image description here

drawilson
  • 37
  • 6
  • Relevant: [How can I obtain an 'unbalanced' grid of ggplots?](https://stackoverflow.com/questions/8112208/how-can-i-obtain-an-unbalanced-grid-of-ggplots) and [Creating arbitrary panes in ggplot2](https://stackoverflow.com/questions/7993722/creating-arbitrary-panes-in-ggplot2) – markus May 01 '19 at 19:47
  • Possible duplicate of [Side-by-side plots with ggplot2](https://stackoverflow.com/questions/1249548/side-by-side-plots-with-ggplot2) – camille May 01 '19 at 19:52

3 Answers3

1

You could try using the plot_grid() function from the cowplot package. You'll find a package vignette https://cran.r-project.org/web/packages/cowplot/vignettes/introduction.html.

In your case, try, cowplot::plot_grid(graph_1, graph_2, graph_3, ncol = 3, align = "h")

Isaac
  • 100
  • 1
  • 7
  • This package drops the grids in my graphs and seems to have a very drawn out way of getting a common legend. I could be wrong so please correct me if so. I am trying to keep as few lines a possible to reduce more likelihood of being in this situation later – drawilson May 01 '19 at 20:20
0

You could also have a go with the grid.arrange() function in the gridExtra package. Here's an example from R Blogger's https://www.r-bloggers.com/extra-extra-get-your-gridextra/. Here's also the package vignette https://cran.r-project.org/web/packages/gridExtra/vignettes/arrangeGrob.html.

Try grid.arrange(graph_1,graph_2,graph_3, ncol = 3)

TheSciGuy
  • 1,154
  • 11
  • 22
0

You might want to have a look at patchwork package.

Alternatively, if all your plots have the same number of rows in terms of graphical elements, you can covert your plots to gtables and cbind (or rbind) them together.

library(grid)
p <- p <- ggplot(iris, aes(Petal.Length, Sepal.Length)) + 
  geom_point() + 
  facet_wrap(~ Species, nrow = 3)

grobs <- ggplotGrob(p)

multi <- cbind(grobs, grobs, grobs, size = "first")

grid.newpage(); grid.draw(multi)

enter image description here

Might be a bit tricky when you have the legend only in the middle plot, since that counts as a row of graphical elements.

If you want to dive into the details you can mess around with gtables, if you want intuitive combining of plots, I suggest the patchwork package.

teunbrand
  • 33,645
  • 4
  • 37
  • 63