R - adding page numbers to PDF

孤街浪徒 提交于 2019-12-01 05:46:37

问题


I'm having trouble adding page numbers to PDFs. Here's how I'm inserting pages / plots:

pdf( file = pdfFilePath , width = 11 , height = 8.5  )
for ( ... ) {
    grid.newpage()
    pushViewport( viewport( layout = grid.layout( 2 , 2 ) ) )
    ... print 4 plots ....
}

onefile seems to name a file by the page number, but I want the page numbers to appear in the same file.

Edit
I've modified @Gavin's code sample to produce a working version of mixing graphic types to get page numbers:

require(ggplot2)
pdf( file = "FILE_PATH_TO_SAVE_PDF_HERE" , width = 11 , height = 8.5  )
par( oma = c ( 4 , 4 , 4 , 4 ) , mar=c( 4 , 0 , 2 , 0 )  )
plot( 0:11 , type = "n", xaxt="n", yaxt="n", bty="n", xlab = "", ylab = ""  )
mtext( side = 3 , line = 0 , outer = TRUE  , cex = 1.5 , family="mono" , "Title" )
grid.newpage()
p1 <- ggplot(data.frame(X = 1:10, Y = runif(10)), aes(x = X, y = Y)) + 
        geom_point()
vplayout <- function(x, y) {
    viewport(layout.pos.row = x, layout.pos.col = y)
}
pushViewport(viewport(layout = grid.layout(2, 2)))
print(p1, vp = vplayout(1,1))
print(p1, vp = vplayout(1,2))
print(p1, vp = vplayout(2,1))
print(p1, vp = vplayout(2,2))
mtext( "1" , side = 1 , line = 3 , outer = TRUE , cex = .8 , family="mono"  )
dev.off()

回答1:


From my second comment on the Q, I suggested a base graphics solution using mtext(). This appears to work for the OP so I show an expanded version here:

Base Graphics:

op <- par(oma = c(2,0,0,0))
layout(matrix(1:4, ncol = 2))
plot(1:10)
plot(1:10)
plot(1:10)
plot(1:10)
mtext(side = 1, text = "Page 1", outer = TRUE)
layout(1)
par(op)

Resulting in:

@SFun28 reports this idea works for his ggplot/grid graphics too, but it does not for me. After running the last line of the code chunk below I get the following error:

> mtext(side = 1, text = "Page 1")
Error in mtext(side = 1, text = "Page 1") : 
  plot.new has not been called yet

which is indicative of the warning not to mix base and grid graphics.

require(ggplot2)
p1 <- ggplot(data.frame(X = 1:10, Y = runif(10)), aes(x = X, y = Y)) + 
        geom_point()
vplayout <- function(x, y) {
    viewport(layout.pos.row = x, layout.pos.col = y)
}
grid.newpage()
pushViewport(viewport(layout = grid.layout(2, 2)))
print(p1, vp = vplayout(1,1))
print(p1, vp = vplayout(1,2))
print(p1, vp = vplayout(2,1))
print(p1, vp = vplayout(2,2))
mtext(side = 1, text = "Page 1")



回答2:


I have modified an example from Paul Murrell's R Graphics book that draws an entire plot using grid and then places a label at the bottom in a separate viewport. I leave the fine tuning to the OP as I don't know what the individual plots are doing, but the general idea of creating an extra viewport (?) across the bottom of the device into which the label is drawn should map onto the grid.layout() ideas already used by @SFun28:

label <- textGrob("A page number! ",
                  x=0.5, y = 1.0, just="centre")
x <- seq(0.1, 0.9, length=50)
y <- runif(50, 0.1, 0.9)
gplot <- 
  gTree(
    children=gList(rectGrob(gp=gpar(col="grey60",
                                    fill="white")),
                   linesGrob(x, y), 
                   pointsGrob(x, y, pch=16, 
                              size=unit(1.5, "mm"))),
    vp=viewport(width=unit(1, "npc") - unit(5, "mm"), 
                height=unit(1, "npc") - unit(10, "mm")))



layout <- grid.layout(2, 1,
                      widths=unit(c(1, 1), 
                                  c("null", "grobwidth"),
                                  list(NULL, label)),
                      heights = unit(c(1, 1),
                                     c("null", "grobheight"),
                                     list(NULL, label)))

grid.rect(gp=gpar(col="grey60", fill="grey90"))
pushViewport(viewport(layout=layout))
pushViewport(viewport(layout.pos.row=2))
grid.draw(label)
popViewport()
pushViewport(viewport(layout.pos.col=1))
grid.draw(gplot)
popViewport(2)

Which gives:




回答3:


library(ggplot2)
plots = replicate(8, qplot(1,1))
library(gridExtra)
p <- 
do.call(marrangeGrob, c(plots, list(ncol=2, nrow=2, top =NULL, 
        bottom = quote(quote(paste(g, "/",pages))))))

p

ggsave("multipage.pdf", p)

(the quote(quote()) is needed to maintain lazy evaluation, somehow)




回答4:


As mentioned by @Gavin, I also encountered the error when mixing ggplot with mtext.

Here is what works really nicely for me when using ggplot:

require(ggplot2)
require(grid)
printWithFooter = function(gg_obj, bottom_left = NULL, bottom_right = NULL) 
{
  print(gg_obj)
  if (!is.null(bottom_right))
  {
    label = textGrob(bottom_right,
                     x = 0.98,  # right side
                     y = 0.0,   # bottom
                     just="right", 
                     hjust = NULL,
                     vjust = -.5,
                     gp=gpar(fontsize=7, col="#333333"))
    grid.draw(label)
  }
  if (!is.null(bottom_left))
  {
    label = textGrob(bottom_left,
                     x = 0.02,  # left side
                     y = 0.0,   # bottom
                     just="left", 
                     hjust = NULL,
                     vjust = -.5,
                     gp=gpar(fontsize=7, col="#333333"))  
    grid.draw(label)
  }
}

## example

d = data.frame(x = runif(1:20), y = runif(1:20), facet = rep(1:4, each=5))
p = ggplot(d) + geom_point(aes(x=x, y=y)) + facet_wrap(~facet)
printWithFooter(p, "left", "right")



来源:https://stackoverflow.com/questions/5735541/r-adding-page-numbers-to-pdf

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