Как использовать разные функции dev.off() с Knitr (для автоматической обрезки фигур)

Я хотел бы использовать собственное pdf() устройство печати в .Rnw документе, преобразованном в PDF с помощью knitr. После создания PDF-файла фигуры он должен вызывать pdfCrop.off() вместо dev.off() (или что-то еще, что вызывает knitr); это идеально обрезало бы полученные фигуры. Как это может быть сделано?

Следующий MWE работает (но без обрезки), если (*) закомментирован (и строка перед правильно закрыта).

\documentclass{article}

\begin{document}
<<knitr_options, echo = FALSE, results = "hide", purl = FALSE>>=
## Custom graphics device (for cropping .pdf):
pdfCrop <- function(file, width, height, ...)
{
    f <- file
    grDevices::pdf(f, width = width, height = height, onefile = FALSE)
    assign(".pdfCrop.file", f, envir = globalenv())
}
pdfCrop.off <- function() # used automagically
{
    grDevices::dev.off() # closing the pdf device
    f <- get(".pdfCrop.file", envir = globalenv())
    system(paste("pdfcrop --pdftexcmd pdftex", f, f, "1>/dev/null 2>&1"),
           intern = FALSE) # crop the file (relies on PATH)
}

## knitr options
knitr::opts_chunk$set(fig.path = "./fig_", background = "#FFFFFF",
                      dev = "pdfCrop", fig.ext = "pdf") # (*) => how to use pdfCrop.off() instead of dev.off()?
@

<<MWE>>=
<<fig-MWE, eval = FALSE, echo = FALSE>>=
plot(1:10, 10:1)
@
\setkeys{Gin}{width=\textwidth}
\begin{figure}[htbp]
  \centering
  \framebox{
<<figMWE, echo = FALSE, fig.width=6, fig.height=6>>=
<<fig-MWE>>
@
}
\caption{Just some text to show the actual textwidth in order to see that the
  figure is not perfectly horizontally aligned due to some white space which can
  be avoided by properly crop the figure with an adequate pdf crop device.}
\end{figure}

\end{document}

person Marius Hofert    schedule 21.03.2019    source источник


Ответы (1)


knitr уже предоставляет устройство обрезки на основе pdfcrop, поэтому мы можем использовать его через хук:

\documentclass{article}

\begin{document}
<<knitr_options, echo = FALSE, results = "hide", purl = FALSE>>=
## knitr options
library(knitr)
knit_hooks$set(crop = hook_pdfcrop)
knitr::opts_chunk$set(fig.path = "./fig_", # all figures are saved as fig_*
                      background = "#FFFFFF", # avoid color
                      crop = TRUE) # always crop
@

<<MWE>>=
<<fig-MWE, eval = FALSE, echo = FALSE>>=
plot(1:10, 10:1)
@
\setkeys{Gin}{width=\textwidth}
\begin{figure}[htbp]
  \centering
<<figMWE, echo = FALSE, fig.width=6, fig.height=6>>=
<<fig-MWE>>
@
\caption{Just some text to show the actual textwidth in order to see that the
  figure is not perfectly horizontally aligned due to some white space which can
  be avoided by properly crop the figure with an adequate pdf crop device.}
\end{figure}

\end{document}
person Marius Hofert    schedule 21.03.2019