2

I'm preparing some html pages using rmarkdown, intended for posting online. When showing plots, I'd like to take advantage of more of the width available on a typical computer monitor (which is how I anticipate my intended audience viewing my pages). knitr by default only seems to use around 900 pixels at regular zoom.

I found some css in this thread which can make the total "canvas" bigger, which is helpful. However, this also increases the width of everything, including text, chunk echoes, etc, which I don't want. What I'd like is to have my figures "overhang" the other elements in width. Increasing fig.width and out.width doesn't accomplish this; the figures will simply shrink to fit within the same bounds used by the other elements, resulting in smaller font size, etc:

<style type="text/css">
.main-container {
  max-width: 1500px;
  margin-left: auto;
  margin-right: auto;
}
</style>

```{r out.width = "150%", fig.width = 12, fig.height = 3, device = "svg", fig.align='center'}
plot(pressure)
```

undesired

Here's a mockup of the kind of thing I'm after, stitched together in Paint: desired

lost
  • 1,483
  • 1
  • 11
  • 19

1 Answers1

3

As you have realized, you should not increase the width of .main-container, but the images instead. Below is one way to achieve it:

---
title: "R Markdown Full-width Figures"
output: html_document
---

```{r out.extra='style="max-width:none; width:100vw; margin-left:calc(50% - 50vw);"', fig.width = 12, fig.height = 3, device = "svg"}
par(mar = c(4, 4.5, 1, .5))
plot(pressure)
```

First, you need to remove the default max-width constraint (which is imposed by rmarkdown) by max-width: none;. Then you set the width of the image to be 100vw, which means the full width of the window. At this point, your image is still left-aligned inside .main-container, i.e., it's left side is aligned with the rest of the body elements, so you need to move the image to the left so that it touches the left margin of the window, which is what margin-left: calc(50% - 50vw) does above. You may draw a box on a piece of paper to understand it. Basically, margin-left: 50% means that the image will first be moved to the right by half of the width of its container (i.e., .main-container). This means its left side is at the center of the container. Since the container is centered on the page, you need to move the image to the left by 50vw (i.e., half of the window width). Moving to the left means giving it a negative left margin, hence -50vw. The calc() function calculates the actual number of pixels dynamically, so you don't have to assume a fixed width for the container.

Once you understand this margin-left trick, you can use other possible widths, e.g., width: 90vw; margin-left: calc(50% - 45vw), which gives you an image with the width 90vw and centered on the page:

an image with the width 90vw

If you do not want to inline the CSS on <img>, you can wrap the code chunk in a fenced Div with a class name, so that you can reuse the CSS defined for the class. Here is an example:

---
title: "R Markdown Full-width Figures"
output: html_document
---

```{css, echo=FALSE}
.fullwidth img {
  max-width: none;
  width: 100vw;
  margin-left: calc(50% - 50vw);
}
```

## One plot

::: {.fullwidth}
```{r, fig.width = 12, fig.height = 3, device = "svg"}
par(mar = c(4, 4.5, 1, .5))
plot(pressure)
```
:::

## Another plot

::: {.fullwidth}
```{r, fig.width = 12, fig.height = 5, device = "svg"}
par(mar = c(4, 4.5, 1, .5))
boxplot(mpg ~ gear, data = mtcars, horizontal = TRUE)
```
:::

Two full-width plots

Yihui Xie
  • 28,913
  • 23
  • 193
  • 419
  • Thanks! How would you get the margins to work for a plotly object? This solution doesn't seem to work for plotly. – lost May 24 '21 at 10:01
  • Basically you need to define CSS for the right elements. In the above example, I was adding the styles right onto ``. In the case of plotly, it's probably a `
    `, and you may need to define the CSS styles in a `css` code chunk for the `div`: https://bookdown.org/yihui/rmarkdown/language-engines.html#javascript-and-css
    – Yihui Xie May 24 '21 at 13:34