【问题标题】:R + ggplot + pdf device + LaTeX: is it possible to embed fonts one timeR + ggplot + pdf device + LaTeX:是否可以一次嵌入字体
【发布时间】:2018-07-22 14:32:26
【问题描述】:

我有一个 r-scipt,它通过以下方式生成 PDF...

  1. 正在使用baseplotggplot 制作100 多个图表。这些图表是使用pdf 设备生成的。我使用 pdf 的原因是我需要嵌入字体(在 tex 标签中使用自定义字体)。
  2. 生成图表后,我调用 Sweave 生成 .tex 以将所有图表收集在一起。
  3. 之后我调用MikTeX生成PDF。

事实证明,生成图表所需的 75-95% 的时间由 embed_fonts 调用占用。有没有办法减少embed_fonts(这似乎是ghostscript的包装)调用?理想的 vatiant 是只嵌入一次调用。这可能吗?

【问题讨论】:

  • 我在创建 4k 页 PDF 文件时遇到了类似的问题。就像120MB大。我最终使用了 acrobat 专业版来“清理”pdf。它基本上删除了所有嵌入的字体,之后我可以用大约 20MB 保存它。找不到比手动完成此步骤更好的解决方案。
  • “将所有图表收集在一起”是什么意思?如果您的意思是将所有数字合并到一个 pdf 中,您可能需要查看 pdftk 并使用类似 pdftk *.pdf cat output mergedfile.pdf 的内容。我猜你可以只在合并的pdf上应用embed_fonts
  • @DJack 我的意思是大的tex 文件有很多\includegraphics[width=\textwidth]{pdfs/graph_made_with_R_12345.pdf}

标签: r pdf ggplot2 latex sweave


【解决方案1】:

也许您可以使用应该嵌入字体的cairo_pdf 设备。
cairo_pdf 似乎比pdf 慢,但比pdf + embedFonts 快​​。

当然,只在最终的 pdf 文档中嵌入字体会是一个更好的解决方案...

library(microbenchmark)

res_pdf <- microbenchmark({
    f = tempfile(fileext = '.pdf')
    pdf(f); pairs(iris); dev.off()
})

res_embed <- microbenchmark({
    f = tempfile(fileext = '.pdf')
    pdf(f); pairs(iris); dev.off()
    embedFonts(f)
})

res_cairo <- microbenchmark({
    f = tempfile(fileext = '.pdf')
    cairo_pdf(f); pairs(iris); dev.off()
})

res_pdf
#> Unit: milliseconds
#>       min      lq     mean   median       uq     max neval
#>  16.67764 17.0388 18.05949 17.32904 18.18776 60.2542   100

res_embed
#> Unit: milliseconds
#>                                                                                               
#>      min       lq     mean   median       uq      max neval
#>  250.046 252.7647 257.4749 255.2785 259.4858 303.0072   100

res_cairo
#> Unit: milliseconds
#>                                                                                   
#>       min       lq     mean   median      uq      max neval
#>  84.25745 86.60512 88.42902 88.36698 89.5705 111.5881   100

【讨论】:

    【解决方案2】:

    另一种解决方案是使用出色的 tikzDevice 包将您的图输出为 TikZ。

    文档中,我们可以包含一个 块,并将设备设置为tikz

    example.Rmd

    ---
    output:
      pdf_document:
        latex_engine: xelatex
    header-includes:
      - \renewcommand{\familydefault}{\sfdefault}
      - \usepackage{tikz}
    ---
    
    ```{r setup, include=FALSE}
    library(tikzDevice)
    
    # setting the package options so that the font metrics are calculated correctly
    options(
      tikzLatexPackages = c(
        getOption("tikzLatexPackages"),
        "\\renewcommand{\\familydefault}{\\sfdefault}"
      )
    )
    ```
    
    # My plot
    
    This text will be set in the default *sans serif* and so will the text found
    within the chart below.
    
    ```{r, echo=FALSE, dev='tikz'}
    pairs(iris)
    ```
    

    您可以将我的\renewcommand{\familydefault}{\sfdefault} 替换为设置所选字体所需的任何乳胶命令,例如\usepackage{charter}。请注意,您必须像上面的示例一样转义 \

    example.pdf

    另类

    鉴于您有这么多的脚本,您可能希望提前使用另一个脚本生成所有绘图,而不是在文档生成时内联编织。我这样做是为了生成大量报告(1,000 多份),每份报告包含大约 20 个图。

    # a more simple example due to output size
    library(tikzDevice)
    mpg <- mtcars$mpg
    
    tikz(file = "example.tex"); hist(mpg); dev.off()
    

    example.tex

    % Created by tikzDevice version 0.10.1.2 on 2018-02-21 23:32:57
    % !TEX encoding = UTF-8 Unicode
    \begin{tikzpicture}[x=1pt,y=1pt]
    \definecolor{fillColor}{RGB}{255,255,255}
    \path[use as bounding box,fill=fillColor,fill opacity=0.00] (0,0) rectangle (216.81,216.81);
    \begin{scope}
    \path[clip] (  0.00,  0.00) rectangle (216.81,216.81);
    \definecolor{drawColor}{RGB}{0,0,0}
    
    \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.20] at (120.41,188.07) {\bfseries Histogram of mpg};
    
    \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.00] at (120.41, 15.60) {mpg};
    
    \node[text=drawColor,rotate= 90.00,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.00] at ( 10.80,114.41) {Frequency};
    \end{scope}
    \begin{scope}
    \path[clip] (  0.00,  0.00) rectangle (216.81,216.81);
    \definecolor{drawColor}{RGB}{0,0,0}
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 54.47, 61.20) -- (186.34, 61.20);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 54.47, 61.20) -- ( 54.47, 55.20);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 80.85, 61.20) -- ( 80.85, 55.20);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (107.22, 61.20) -- (107.22, 55.20);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (133.59, 61.20) -- (133.59, 55.20);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (159.96, 61.20) -- (159.96, 55.20);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (186.34, 61.20) -- (186.34, 55.20);
    
    \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.00] at ( 54.47, 39.60) {10};
    
    \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.00] at ( 80.85, 39.60) {15};
    
    \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.00] at (107.22, 39.60) {20};
    
    \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.00] at (133.59, 39.60) {25};
    
    \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.00] at (159.96, 39.60) {30};
    
    \node[text=drawColor,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.00] at (186.34, 39.60) {35};
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20, 65.14) -- ( 49.20,163.67);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20, 65.14) -- ( 43.20, 65.14);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20, 81.56) -- ( 43.20, 81.56);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20, 97.98) -- ( 43.20, 97.98);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20,114.40) -- ( 43.20,114.40);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20,130.83) -- ( 43.20,130.83);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20,147.25) -- ( 43.20,147.25);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 49.20,163.67) -- ( 43.20,163.67);
    
    \node[text=drawColor,rotate= 90.00,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.00] at ( 34.80, 65.14) {0};
    
    \node[text=drawColor,rotate= 90.00,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.00] at ( 34.80, 81.56) {2};
    
    \node[text=drawColor,rotate= 90.00,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.00] at ( 34.80, 97.98) {4};
    
    \node[text=drawColor,rotate= 90.00,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.00] at ( 34.80,114.40) {6};
    
    \node[text=drawColor,rotate= 90.00,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.00] at ( 34.80,130.83) {8};
    
    \node[text=drawColor,rotate= 90.00,anchor=base,inner sep=0pt, outer sep=0pt, scale=  1.00] at ( 34.80,147.25) {10};
    \end{scope}
    \begin{scope}
    \path[clip] ( 49.20, 61.20) rectangle (191.61,167.61);
    \definecolor{drawColor}{RGB}{0,0,0}
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 54.47, 65.14) rectangle ( 80.85,114.40);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] ( 80.85, 65.14) rectangle (107.22,163.67);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (107.22, 65.14) rectangle (133.59,130.83);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (133.59, 65.14) rectangle (159.96, 81.56);
    
    \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round] (159.96, 65.14) rectangle (186.34, 97.98);
    \end{scope}
    \end{tikzpicture}
    

    注意这不是一个完整的 .tex 文件,而是设计为使用 \input{example.tex} 引入或嵌入到完整的文档中。另外,请注意字体度量计算,如果度量明显超出,保存的.tex 文件可能会以不同的字体呈现出奇怪的效果。

    【讨论】:

      【解决方案3】:

      我尝试在第 3 步生成的 PDF 上执行 embed_fonts,而不是在第 1 步生成的每个图形上调用它,这似乎没问题

      【讨论】:

        猜你喜欢
        • 2015-02-16
        • 1970-01-01
        • 2018-02-10
        • 1970-01-01
        • 2010-12-13
        • 2011-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多