7

Within RStudio my plots look perfect, but when I generate HTML via the "knit HTML" button my margins are being cut off.

I am using the base graphics package to create a simple barplot.

I have a large lower margin to accommodate vertical labels across the x-axis, and a wide left margin to keep the y-axis title to the left of some large numbers, e.g.:

```{r set-graph-options}
par(mar = c(12, 6, 4, 2) + 0.1, mgp = c(4, 1, 0), las = 2)
```

Both the x-axis and y-axis labels/titles are affected; with the default mgp setting my ylab setting appears fine, but with a larger value it seems to be pushed off the "canvas" (or whatever the terminology is in R).

I also notice that knitr/rmarkdown does not recognize the globally set par() options. For example, after setting the above, barplot(injury_top12, ylab = "Injuries") will recognize none of the mar, mgp, or las options, but if I copy the options into the barplot() call itself, las = 2 & mgp = c(4, 1, 0) begin to work, but mar is still not recognized.

I have tried generating the HTML from the command line with the command R -e "rmarkdown::render('Readme.Rmd')", which exhibited the same problem.

I am using R Studio 0.98.1103, knitr is 1.11, rmarkdown is 0.8, OS is ubuntu linux.

Example.Rmd:

```{r echo = F, example-set-par}
library(knitr)
opts_knit$set(cache = FALSE, verbose = TRUE, global.par = TRUE)
par(mar = c(12, 6, 4, 2) + 0.1, mgp = c(4, 1, 0), las = 2)
d <- c("This is a longer than usual label" = 355,
       "Another quite long label" = 144,
       "A third longish label for a barplot" = 222)
```

Plot one depends on values set by `par()`:

```{r echo = F, example-plot-using-par}
barplot(d, ylab = "Arbitrary numbers")
```

Plot two explicitly sets options:

```{r echo = F, example-plot-with-explicit-options}
barplot(d, ylab = "Arbitrary numbers", mar = c(12, 6, 4, 2) + 0.1, mgp = c(4, 1, 0), las = 2)
```

When I knit this Rmd doc, the first plot does not use the las or mgp options set in par(). The second plot does, but the x-axis labels are cut off, and the y-axis title is pushed almost entirely out of the frame (the tail of the y is slightly visible).

example image

Kenneth D.
  • 845
  • 3
  • 10
  • 18
  • 1
    Usually when you knit a document the R code is evaluated in a new session, so if you set `par` options you'll need to do it inside the document. Perhaps you could give a reproducible example? – Gregor Thomas Sep 28 '15 at 17:45
  • Thanks, @Gregor. Of course I am setting `par()` within the document. I added an Example.Rmd & screenshot of the output. – Kenneth D. Sep 28 '15 at 19:00
  • You may see https://twitter.com/xieyihui/status/634757554653020160 – Yihui Xie Sep 28 '15 at 21:16
  • Thanks @Yihui, I edited my post to reflect the current state of my Example.Rmd, there was no change after adding "opts_knit$set(global.par = TRUE)". I tried it several times & verified there was no cache involved, just to convince myself it wasn't something stupid on my part – Kenneth D. Sep 28 '15 at 23:33
  • You need to set this option in a separate code chunk so it can be applied to following chunks. – Yihui Xie Sep 29 '15 at 04:14
  • @Yihui, they are in separate code chunks -- or do I misunderstand? The first chunk sets `opts_knit$set(global.par = TRUE)` & sets some options with `par()`, the calls to `barplot()` are in two other chunks. – Kenneth D. Sep 29 '15 at 15:07
  • I mean `opts_knit$set()` and `par()` have to be in separate chunks. – Yihui Xie Sep 29 '15 at 17:20
  • @Yuhui, aha! It does work when I separate those two. Thanks so much! The longest of the x-axis label is still cut off a little bit, but I can live with it. If you'd like to create an answer, I will approve it. – Kenneth D. Sep 29 '15 at 17:53

1 Answers1

6

For people that want directly the answer hidden within the comment and a tweet, your .Rmd file should look like:

---
title: exemple
header of your Rmd
---

```{r}
library(knitr)
opts_knit$set(global.par = TRUE)
```
The important think in the previous chunk is  to put global.par=TRUE 

Plot one depends on values set by `par()`:

```{r}
par(mar=c(5,5,0,0)) #it's important to have that in a separate chunk
``` 
Now we just plot a point with the good margin set by the global `par()`

```{r}
plot(1,1,main="a plot with the margin as set globally")
```

if you don't want to include the code used to set the global margin in the output just add :

```{r,include=FALSE}
par(mar=c(5,5,0,0))
``` 

in the chunk you don't want to include.

Simon C.
  • 1,058
  • 15
  • 33