Łukasz Deryło
Łukasz Deryło

Reputation: 1860

RMarkdown plot inserted into Word with 101% width and height

Just like in Title: no matter how fancy or simple a plot I insert into Word from RMarkdown, I get an image with 101% height and width. This is annoying because this makes plots look blurred.

Example

This short .Rmd file:

---
output:
  word_document

---

```{r, echo=F}
plot(1:100)
```

knits to this:

enter image description here

Then I right-click on it, select Properties and see it was inserted with 101% of original size (strange language below is polish ;) )

enter image description here

When I reset it to 100%, it looks much nicer:

enter image description here

Question How to force RMarkdown to insert plots with 100% width and height?

What I've tried

(none of these work)

Upvotes: 3

Views: 3162

Answers (1)

RLesur
RLesur

Reputation: 5910

First, note that when this knitr feature request will be implemented, you will must stop using the following answer.

This problem can be solved using pandoc link attributes. As explained in the pandoc documentation, without link attributes "the fallback is to look at the image resolution and the dpi metadata embedded in the image file" (I think the trouble comes from this fallback method).

Link attributes is a recent pandoc feature, introduced in pandoc 1.16. It is not yet supported by knitr, but will be soon according to the above-mentioned feature request.

As long as knitr does not support pandoc link attributes, here is a hacky proposal to solve this problem. It uses a knitr plot hook.

---
output: word_document
---

```{r setup, echo=FALSE}
default_plot_hook <- knitr::knit_hooks$get('plot')

knitr::knit_hooks$set(plot = function(x, options) {
  default_md <- default_plot_hook(x, options)
  link_attr <- sprintf("{width=%sin height=%sin}", options$fig.width, options$fig.height)
  sub("(!\\[.*]\\(.*\\))", paste0("\\1", link_attr), default_md)
})
```

```{r, echo=F}
plot(1:100)
```

Explanations
The first step of the rendering process of a RMarkdown file (.Rmd) is to produce a plain markdown file (.md). This is the job of knitr.

The second step of the process is to produce the word file (.docx) from this markdown file. This is the job of pandoc.

Note that you can inspect this intermediate markdown file using the keep_md option in the YAML header:

---
output: 
  word_document:
    keep_md: true
---

With the available versions of knitr, a link to an image is rendered by knitr like this:

![](myreport_files/figure-docx/unnamed-chunk-1-1.png)<!-- -->

There is no link attributes, so pandoc determines the dimensions of the image using its fallback method.

The proposed knitr plot hook add width and height attributes to the link.
It returns the following markdown:

![](myreport_files/figure-docx/unnamed-chunk-1-1.png){width=5in height=4in}<!-- -->

Therefore, pandoc determines the dimensions of the image from these attributes and not from the fallback method.

Obviously, to use this proposal, your pandoc version has to be >= 1.16.

Upvotes: 4

Related Questions