使用knitr和pandoc转换为PDF时markdown中的图形位置

Posted

技术标签:

【中文标题】使用knitr和pandoc转换为PDF时markdown中的图形位置【英文标题】:Figure position in markdown when converting to PDF with knitr and pandoc 【发布时间】:2013-05-13 15:36:04 【问题描述】:

我试图在使用 knitr 和 pandoc 转换为 PDF 时控制绘图的位置。我的 .Rmd 文件如下所示:

# My report

Some text some text some text some text some text some text some text some text some text


```r myplot, echo=FALSE, fig.pos="placeHere", results='hide'

library(ggplot2)

ggplot(mtcars, aes(mpg, drat)) + geom_point()

```

Some text some text some text some text some text some text some text some text some text

\usepackagegraphicx
\beginfigure[placeHere]
  \centering
    \includegraphics[width=0.5\textwidth]placeHere
\endfigure

Some text some text some text some text some text some text some text some text some text

我正在使用此处提供的功能转换为 PDF:http://quantifyingmemory.blogspot.co.uk/2013/02/reproducible-research-with-r-knitr.html

如何将绘图放置在第二个和第三个文本块之间?乳胶代码无法按目前的方式工作。

编辑:这就是我现在正在尝试的。

# My report

   ```r setup, include=FALSE
# set global chunk options
opts_chunk$set(cache=FALSE)
library(ggplot2)
```

```r, echo=FALSE, fig.height=3

ggplot(mtcars, aes(disp, hp)) + geom_point()


```



Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some textSome text Some text Some text 

Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some textSome text Some text Some text 


Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some textSome text Some text Some text 


Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some textSome text Some text Some text 


```r, echo=FALSE, fig.height=3



ggplot(mtcars, aes(vs, am)) + geom_point()


```



Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some textSome text Some text Some text 

Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some textSome text Some text Some text 


Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some textSome text Some text Some text 


```r, echo=FALSE, fig.height=6



ggplot(mtcars, aes(disp, cyl)) + geom_point()

```


```r, echo=FALSE, fig.height=6

ggplot(mtcars, aes(hp, qsec)) + geom_point()


```


Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some textSome text Some text Some text 




```r, echo=FALSE, fig.height=3

ggplot(mtcars, aes(hp, wt)) + geom_point()

```



Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some textSome text Some text Some text 



```r, echo=FALSE, fig.height=5

ggplot(mtcars, aes(mpg, drat)) + geom_point()

```




Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some textSome text Some text Some text 

【问题讨论】:

我可能在这里不正常,但我认为您正在尝试控制乳胶。您想使用浮动放置,如 here 所示。 你是否混合了 knitr 的 Rnw 和 Rmd 语法编码? 我查看了 wiki 页面,并尝试遵循代码。但是仍然没有将情节放在我想要的地方。使用我尝试过的代码更新帖子 你知道乳胶吗?如果是这样,请制作和 Rnw 文件并使用乳胶编码。如果你真的想使用 Rmd 然后在你做的时候进行转换,你不能以这种方式插入一个数字(据我所知)。您需要插入 html 方式(可能使用 ![](path/to/image)。您也可以在 html 中使用 captions。您也可能只想使用 [html <img> ](w3schools.com/tags/tag_img.asp) 标签来放置图像. 我已经用我的真实文档尝试了 html 方法 ![](path/to/image) 并且数字放置的行为是相似的。因此,在我告诉他们要打印的地方,数字并没有打印出来(通常它们在文档中的位置较高)。 【参考方案1】:

我提出了一个替代解决方案。我建议不要以事后的方式将 [H] 符号插入到 Latex 文档中,而是重新定义图形环境以忽略任何位置参数并使用 [H]。

为此,请在与重新定义图形环境的 .Rmd 文件相同的目录中创建一个 .tex 文件,并更新 .Rmd 中的 YAML 标头以在编译期间包含该文件。

这是一个 .tex 文件的示例:

\usepackagefloat
\let\origfigure\figure
\let\endorigfigure\endfigure
\renewenvironmentfigure[1][2] 
    \expandafter\origfigure\expandafter[H]
 
    \endorigfigure

这是包含它的示例 .Rmd(假设您将 .tex 文件称为“preamble-latex.tex”):

---
title: "example"
author: "you"
date: "`r format(Sys.time(), '%d %B %Y')`"
output:
  rmarkdown::pdf_document:
    fig_caption: yes        
    includes:  
      in_header: preamble-latex.tex
---

```r, fig.cap='Markdownvellous!'
plot(1:10, 1:10)
```

【讨论】:

这很好用,并且比接受的答案恕我直言要好得多。但是,您可以简化,因为此处对小插图等的引用无关紧要。 完美解决方案。找了一阵子 我也一直在努力解决这个问题。非常感谢:-) 我绝对同意这个答案比我的(五年前发布)更优雅,我鼓励 OP 改为接受这个答案。 我在这里尝试了多种其他解决方案。这是唯一有效的方法。【参考方案2】:

我不知道pandoc 在将 Markdown 文档转换为 LaTeX 时设置图形浮动选项的这种选项。如果您选择 Markdown 是因为它的简单性,那么即使使用像 pandoc 这样的强大工具,您也不应该期望它有太多的功能。底线:Markdown 不是 LaTeX。它是为 HTML 而不是 LaTeX 设计的。

两种方法:

    使用 Rnw 语法 (R + LaTeX) 而不是 Rmd (R Markdown) (examples);那么您将能够在序言中的\usepackagefloat 之后使用块选项fig.pos='H';在这种情况下,你拥有了 LaTeX 的全部功能,pandoc 不会参与其中

    破解由 pandoc 生成的 LaTeX 文档,例如像

    library(knitr)
    knit('foo.Rmd')  # gives foo.md
    pandoc('foo.md', format='latex')  # gives foo.tex
    x = readLines('foo.tex')
    # insert the float package
    x = sub('(\\\\begin\\document\\)', '\\\\usepackagefloat\n\\1', x)
    # add the H option for all figures
    x = gsub('(\\\\begin\\figure\\)', '\\1[H]', x)
    # write the processed tex file back
    writeLines(x, 'foo.tex')
    # compile to pdf
    tools::texi2pdf('foo.tex')  # gives foo.pdf
    

如果您不喜欢这些解决方案,请考虑 requesting a new feature 在 Github 上进行 pandoc,然后坐等。

【讨论】:

因为我花了 20 分钟才找到它,我在这里发表评论,@yihui 和团队在 bookdown 中包含了一个特殊选项:bookdown.org/yihui/rmarkdown-cookbook/…【参考方案3】:

我在 RSTUDIO 中使用 KnitR 和 markdown,我的情况的解决方案是在序言中添加 \usepackagefloat:

    ---
title: "Proyect 2"
author: "FV"
date: "2016-12-3"
output:
  pdf_document:
    fig_caption: yes
    fig_crop: no
    fig_height: 2
    fig_width: 3
    highlight: haddock
    keep_tex: yes
    number_sections: yes
    toc: yes
    toc_depth: 2
  html_document:
    fig_caption: yes
    theme: journal
    toc: yes
    toc_depth: 2
header-includes: 
- \usepackagegraphicx
- \usepackagefloat
---

然后在第一行添加这行代码 (fig.pos='H'):

```r echo=FALSE,warning=FALSE
 library(knitr)
  opts_chunk$set(fig.path='figure/graphics-', 
                 cache.path='cache/graphics-', 
                 fig.align='center',
                 external=TRUE,
                 echo=TRUE,
                 warning=FALSE,
                 fig.pos='H'
                )
  a4width<- 8.3
  a4height<- 11.7
```

【讨论】:

我刚刚发现,万一它不起作用改变:fig.pos='H' with fig.pos="H",带双引号 我不能与您的经验相矛盾,但总的来说这不重要。在 R 中,单引号和双引号之间的解释没有区别。 ***.com/a/20572492/34935【参考方案4】:

如果您正在寻找的只是手动控制放置图形的位置,请使用此网页:http://www.rci.rutgers.edu/~ag978/litdata/figs/,我发现如果您在绘图命令后的某处添加一个反斜杠“\”,则绘图将不会浮动,而是将打印在其当前位置。

如果您只想显示一些图,您可以为每个图修改该选项。

在你的例子中:

# My report

```r setup, include=FALSE
# set global chunk options
knitr::opts_chunk$set(cache=FALSE)

library(ggplot2)
```

Some text Some text Some text Some text Some text Some text Some text Some       text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some textSome text Some text Some text 

```r, echo=FALSE, fig.height=3
ggplot(mtcars, aes(disp, hp)) + geom_point()
```
\

Some text Some text Some text Some text Some text Some text Some text Some       text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some text Some textSome text Some text Some text 

(等)

【讨论】:

对我来说,这会破坏图形标题和图形对齐方式。 这是第一个对我有用的建议!这也适用于在块的 outside 中包含文件中的图像。非常感谢!【参考方案5】:

我有几个项目从 .Rmd 转换为 .pdf(主要是投影仪幻灯片演示),并且希望图表不浮动(浮动数字确实不适用于幻灯片演示)。

我使用的方法是在 .md 文件的行之后添加一个转义空格。这意味着图表在段落内部而不是它自己的段落,这意味着 pandoc 不会将其包装在图形环境中(这也意味着我不能对其使用标题),因此将其准确地放置在那个位置。

我使用 Makefile 为我完成所有转换,因此在运行 R 和 knitr 后,它会自动运行 Perl 脚本(尽管它可以使用 R 或其他工具完成)找到插入图的位置并添加在行尾转义空格。

【讨论】:

这个答案为我解决了这个问题。对于不知道转义空格是什么的人,您可以使用如下反斜杠:![SourceTree commit message](images/sourcetree-commit-message.png)\ 【参考方案6】:

使用编织钩

我不知何故偶然发现了这个问题,并想添加另一种方法。在这里,我利用了 knitr hooks 提供的出色灵活性。我只是将绘图钩子更改为使用 knitr 函数hook_plot_tex()。之后我可以像我们在 Rnw 文档中习惯的那样使用块选项 fig.pos 来定位 figure 环境(必须设置 fig.cap 才能调用 figure 环境)。

这适用于 OP 提供的示例。我想他们也可以在(不知何故)更复杂的例子中工作。为什么这可以很容易地完成并且不是 Rmd 文档的默认设置,我不确定。或许易辉可以澄清一下。

代码如下:

---
title: "Example"
author: "Martin"
output: pdf_document
---

```r
knitr::knit_hooks$set(plot = function(x, options)  
  hook_plot_tex(x, options)
)
```


```r myplot, echo=FALSE, results='hide', fig.cap='Test', fig.pos='h'
library(ggplot2)
ggplot(mtcars, aes(mpg, drat)) + geom_point()
```

没有fig.pos='h',剧情一般会跳转到第二页。

【讨论】:

如果pandoc抛出错误,一定要加上fig.pos = 'h'。【参考方案7】:

这是你想要的吗:

```r setup, include=FALSE
# set global chunk options
opts_chunk$set(cache=FALSE)
library(ggplot2)
```

# My report

Some text some text some text some text some text some text some text some text some text

Some text some text some text some text some text some text some text some text some text

```r myplot, echo=FALSE

ggplot(mtcars, aes(mpg, drat)) + geom_point()

```

Some text some text some text some text some text some text some text some text some text

【讨论】:

如果在每个图中保持图形高度相同,这似乎可行。但如果不同的身材高度不起作用。我编辑了帖子以更准确地反映我的实际文档的样子。如果您尝试我的代码,您会发现 PDF 中的绘图顺序与 .Rmd 文件中的顺序不同。 你看过knitr's documentation吗? out.height='380px' 请花一些时间阅读文档。 Yihui 花费了大量时间制作了出色的文档和极少的示例。 花了更多时间处理这个问题,我意识到当 .md 文件(由 knitr 输出)转换为 .pdf 文件(由 Pandoc 提供)时会出现问题。在 .md 文件中的 html 代码中添加反斜杠控制图形放置,如下所示: ` ![plot of chunk unnamed-chunk-1](figure/unnamed-chunk-1.png)\ ` 但是,这引入了新问题:图形标题丢失。问题还在继续……!【参考方案8】:

解决方案不太简单,也许其他人可以简化它。

基本步骤。 (Windows 7)

    您可以将参数 fig.pos="H" 添加到 knitr 选项中,无论是全局还是每个单独的块。注意大写的 H。这指示 Latex 将图形浮动准确放置在 Rmd 文件中调用它们的位置。

    但是,这需要latex使用的包,这个你可以在pandoc用来构造pdf文件的模板中指定。您可以通过添加行 \usepackagefloat

    但是,您首先需要找到当前模板文件进行修改。我在任何地方都找不到这个,但你可以让 pandoc 使用以下命令将模板的内容打印到控制台:pandoc -D latex

    将此模板代码剪切并粘贴到一个空文本文件中。

    添加行:\usepackagefloat

    以文件名"default.latex"保存在C:\Users\YOURNAME\pandoc\templates等目录中

    如果在 R 中使用 pander,请将选项 --data-dir=C:/Users/YOURNAME/pandoc/templates" 添加到 pandoc 或 Pandoc.convert("my file.md", format="pdf", options=c("--data-dir=C:/Users/YOURNAME/pandoc/templates"))

我希望这对你有用。

【讨论】:

此人试图从 Rmd 文件而非 Rnw 文件制作 html2pdf 文档。 你说得对,对不起。它不起作用。我不知道为什么我会这么认为。

以上是关于使用knitr和pandoc转换为PDF时markdown中的图形位置的主要内容,如果未能解决你的问题,请参考以下文章

R Markdown、Knitr、Pandoc和Bookdown之间的关系

安装 MikTex、pandoc 和 nbconvert 后将 Jupyter Notebook 转换为 PDF 时出错

使用 knitr、Rmarkdown 和 pandoc 创建 HTML 幻灯片

windows使用Pandoc将Markdown转换为PDF文件

如何使用 knitr 为降价设置本地图像的大小?

使用 pandoc 在 pdf 文件中导出所有 yaml 书目