3

I want to plot a grid and base plot in the same plot in a pdf output. I see how to add grid plus base in several places including here: Combining grid.table and base package plots in R figure and R put together traditional plot and ggplot2

I also want to control the widths of the plots using a proportion or relative width. I thought I had it with the code below unto I tried to output to a pdf and then it prints a blank page before the plot. How can I make it not plot a blank page? I'm not married to any package I would just like the answer to be generalizable (simple is a plus; I feel like my code below could be simplified).

library(ggplot2); library(grid); library(gridBase)

pdf("test.pdf")

grid::grid.newpage()
grid::pushViewport(grid::viewport(layout = grid::grid.layout(1, ncol=2,
    widths = grid::unit(c(.6, .4), "npc"))))

#Draw base plot
grid::pushViewport(grid::viewport(layout.pos.col = 1, width = grid::unit(.8, "npc")))

graphics::plot.new()
graphics::par(fig = gridBase::gridFIG(), mar=c(1, 1, 1, 1), new = TRUE)


plot(1:10)

grid::popViewport()

#Draw ggplot
grid::pushViewport(grid::viewport(layout.pos.col = 2, width = grid::unit(.2, "npc")))
print( ggplot(mtcars, aes(mpg, hp)) + geom_point(), newpage = FALSE)
grid::popViewport()

dev.off()

Plot looks like:

enter image description here

zx8754
  • 52,746
  • 12
  • 114
  • 209
Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
  • 3
    the culprit seems to be in `gridBase::gridFIG()` which in turns calls `gridBase:::currentViewportLoc()`, which contains calls such as `width <- convertWidth(unit(1, "npc"), "inches", valueOnly = TRUE)` which are known to trigger unwanted new pages. Maybe you could avoid it by playing around with a custom version of gridFIG not doing those conversions but using something like par(din) instead. – baptiste Feb 16 '16 at 03:46

2 Answers2

4

You might have better luck with the gridGraphics package, though things aren't completely smooth either,

enter image description here

library(gridGraphics)

grab_grob <- function(){
  grid.echo(newpage=TRUE)
  grid.grab()
}

par(mar=c(4,6,1,1)) # for some reason need lots of space
plot(1:10)
bg <- grab_grob()
p <- ggplot(mtcars, aes(mpg, hp)) + geom_point()

ggsave("test.pdf", gridExtra::arrangeGrob(bg, p, widths = c(2,1)))
baptiste
  • 75,767
  • 19
  • 198
  • 294
2

Here's an approach that removed the gridBase::gridFIG that @baptiste points out to be the problem. I pseudo-hack the widths.

library(ggplot2); library(grid); library(gridBase)

pdf("test.pdf")

widths <- c(.335, .665)
widths <- 100*round(widths/sum(widths), 2)

layout(matrix(c(rep(1, widths[1]), rep(2, widths[2])), nrow = 1,  byrow = TRUE))

#Draw base plot
plot.new()
graphics::par(mar=c(1, 1, 1, 1), new = TRUE)

plot(1:10)

#Draw ggplot
plot.new()
vps <- baseViewports()
print( ggplot(mtcars, aes(mpg, hp)) + geom_point(), vp = vpStack(vps$figure,vps$plot))

dev.off()
Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519