R: Print ggplots and matrices to panels in PDF? - r

I'm creating a multipage PDF, where each page should contain 2 graphs (ggplot2) and 2 matrices. Previously, I was using plot(), where the code and PDF layout for each page was something like this:
pdf("Rplots.pdf", paper = "letter", width = 7.5, height = 10)
layout(matrix(c(1,1,2,4,3,3),3,2, byrow = TRUE), heights = c(7,4,7))
# Plot at the top of each page
plot(dataTop)
# Summary at the bottom of each page
summary <- matrix(dataTop, ncol = 2, nrow = 6)
textplot(summary)
# Plot at the top of each page
plot(dataBottom)
# Summary at the bottom of each page
summary <- matrix(dataBottom, ncol = 2, nrow = 6)
textplot(summary)
dev.off()
I've replaced the plot() with ggplot() and have trouble getting it to print using the same panel layout.
1) Is there any simple way to print a combination of ggplots and matrices using the type of layout I have above?
2) Is there some way to ensure the ggplot is confined/expanded to some certain amount of space on the PDF?
Thank you!

Related

Output multiple plots to a single pdf in for loop

I am having trouble generating a pdf with multiple plots. When I arrange my plots in a for loop it seems it looses the connection to the pdf and produces an empty pdf.
I have a list of lists called p, with p.length(p) ==2.
p[[1]] and p[[2]] contain ggplots.
########## This works ##########
myPDFPath = "output/countryProfilesIndividual_testI.pdf"
pdf(file=myPDFPath, onefile = TRUE)
gridExtra::marrangeGrob(p[[1]], nrow = length(p[[1]]), ncol = 1, top=quote("My Quote"))
gridExtra::marrangeGrob(p[[2]], nrow = length(p[[2]]), ncol = 1, top=quote("My Quote"))
dev.off()
--> Here I get two pages with plots as expected.
########## This works NOT ##########
myPDFPath = "output/countryProfiles.pdf"
pdf(file=myPDFPath, onefile = TRUE)
for (listIdx in 1:length(p))
{
gridExtra::marrangeGrob(p[[listIdx]], nrow = length(p[[listIdx]]), ncol = 1, top=quote("MyQuote"))
}
dev.off()
--> The file is written, but it is empty
Do curly brackets cause some behaviour that I am not aware of?
Please note, I don't want to create individual pdfs, but bring everything in one pdf together.
I want to arrange the plots dynamically, so all lapply possibilities I found don't help me because e.g. the nrow or top parameters have to be set individually.

Plot ggplots stored in list over several pages

I know similar questions have been already asked so sorry if this is a redundant question! However, I can't seem to find a solution that arranges several ggplots from a list onto 1 page over several pages.
I have a list of approximately 100 ggplots - I want to plot every 4 ggplots on 1 page, and iterate through the list until all the ggplots have been plotted. I then want to export the approximately 25 pages to a single pdf file.
So far, I've tried:
pdf("plots.pdf", onefile = TRUE, width = 11, height = 8.5)
for (i in 0:24) {
ggarrange(list[[4i+1]], list[[4i+2]], list[[4i+3]], list[[4i+4]],
nrow = 2, ncol = 2, common.legend = TRUE, legend = 'bottom'
}
dev.off()
However, I'm getting the error that the subscript is out of bounds. I've tried narrowing the range in the for loop to try to overcome this error but it's returning the same error. I also know we can use marrangeGrob(), but I can't seem to add a common legend to the file.
Really appreciate any help!
It would be helpful if you could provide some small list of plots to test on.
I have tried to recreate your scenario, and have found that it wasn't working unless I explicitly print the ggarrange object.
plot <- ggplot(mtcars, aes(x = cyl, y = mpg)) +
geom_point()
plot_list <- list(plot, plot, plot, plot, plot, plot, plot, plot)
pdf("test.pdf", 11, 8.5)
for(i in 0:3){
print(ggarrange(plot_list[[2*i + 1]], plot_list[[2*i + 1]], nrow = 2, ncol = 1))
}
dev.off()
This worked for me. Noting akrun's comment that you forgot your * symbol.

r-grid.arrange. When I make the plots they overlap. How do I get them to not overlap

I am trying to make an arrangement of ggplots. I am able to set it up but the plots overlap. How do I fix this?
grid.arrange(NFL_Plot, NBA_Plot, MLB_Plot, NHL_lot,NASCAR_Plot, CBB_Plot, CFB_Plot,
ncol = 3, nrow = 3)`
This is what it looks like when I run the code

Arrange base plots and grid.tables on the same page

I have 2 plots (created using Base graphics) and 2 data frames that I would like to combine onto one sheet in a PDF. I'm using grid.table to create a tableGrobs from my data frames. I'm having a lot of difficulty formatting the PDF output. In particular, I've been unsuccessful keeping all the objects on the same page. I want the right pannel to contain one graph, and the left panel to contain the other graph, and 2 tables below (landscape format).
Currently my code is something like the following:
library('gridExtra')
pdf("Rplots.pdf", paper = "USr", height = 8.5, width = 11)
layout(matrix(c(1,3, 2,3, 4,3), nrow = 3, ncol = 2, byrow = TRUE))
plot(myPlot1)
grid.table(df1)
plot(myPlot2)
grid.table(df2)
dev.off()
I do not want to use ggplot2.
To combine base plots and grid objects the package gridBase is useful.
A rough worked example base on your layout above
library(grid)
library(gridBase)
library(gridExtra)
layout(matrix(c(1,3, 2,3, 4,3), nrow = 3, ncol = 2, byrow = TRUE))
# First base plot
plot(1:10)
# second base plot
frame()
# Grid regions of current base plot (ie from frame)
vps <- baseViewports()
pushViewport(vps$inner, vps$figure, vps$plot)
# Table grob
grob <- tableGrob(iris[1:2,1:2])
grid.draw(grob)
popViewport(3)
# third base plot
plot(1:10)
# fourth
frame()
vps <- baseViewports()
pushViewport(vps$inner, vps$figure, vps$plot)
grid.draw(grob)
popViewport(3)
Which gives

Nested mfrow and layout

I have a plotting function that just uses base graphics to draw a two-pane plot, using layout. What I would like is to iterate through thousands of objects, and save the plots to a .pdf file, with three of the two-pane plots per page.
Quick dummy example:
examplefunc <- function() {
layout(mat = matrix(1:2, nrow = 1), widths = 3:4, heights = 3)
plot(0)
plot(0)
}
pdf("exmaple.pdf", height = 10, width = 8)
par(mfrow = c(3,1)) # Also tried using layout here.
examplefunc()
examplefunc()
examplefunc()
graphics.off()
The output is a three page .pdf, rather than the desired one page .pdf with three figures. I'd like to keep using layout to get the proportions of the figures correct.
As the help page for layout says, it is incompatible with par(mfrow and other forms of multiple plotting and using layout overrides instead of nests a previous call to layout. So this will be very difficult.
The simplest approach would be to remove the call to layout from the function and set up the grid of 6 panels outside the function. If you wrote the function then that is straight forward, but if using a function from a package then this becomes more difficult. You can either create your own version of the function without layout or some functions have options to only plot one of their plots (and you would just call it multiple times).
Another approach would be to set the pdf file to have 1/3rd the usual height and plot each pair to one page, then use an external tool to combine sets of 3. Tools like Imagemagick or pdftk may help.
Each time you call layout or par you create a new plotting window. Instead, you should only call layout once. For example,
examplefunc <- function() {
plot(0); plot(0)
}
Then
pdf("/tmp/exmaple.pdf", height = 10, width = 8)
layout(mat = matrix(1:6, ncol = 2, byrow=T), widths = 3:4, heights = c(3, 3, 3))
examplefunc()
examplefunc()
examplefunc()
graphics.off()
You can see the layout of the plots via
layout(mat = matrix(1:6, ncol = 2, byrow=T),
widths = 3:4, heights = c(3, 3, 3))
layout.show(6)

Resources