danh
danh

Reputation: 638

How do I add spacing between dygraphs generated in apply loop in Rmarkdown?

This question is related to For loop over dygraph does not work in R

This answer by @Yihui nicely details how to create dygraphs plots in a loop in rmarkdown. But, as you will notice, there is no spacing between the plots. This becomes quite difficult to read when there are many of them.

```{r}
library(dygraphs)
lungDeaths <- cbind(mdeaths, fdeaths)

res <- lapply(1:2, function(i) dygraph(lungDeaths[, i]))
htmltools::tagList(res)
```

Is there a way to add spacing, text, a horizontal rule, etc. between each plot generated here within the custom apply function itself?

My current work-around is to pass in a dyOptions titleHeight argument, along with a dyCSS argument pointing to an external CSS which sets padding on top of the title. For example, I may set the titleHeight argument to 50px, and then set the title itself to 25px, with a top padding height of 25px.

---
title: "test"
author: "test"
date: "test"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
``` 

```{r}
library(dygraphs)
lungDeaths <- cbind(mdeaths, fdeaths)

res <- lapply(1:2, function(i) {
    dygraph(lungDeaths[, i], main = "Lung Deaths") %>%
        dyOptions(titleHeight = 50) %>%
        dyCSS("dygraph.css")
    })
htmltools::tagList(res)
```

And the dygraphs.css file:

.dygraph-title {
      font-size: 25px;
      padding-top: 25px;
}

And if I don't want a plot title, but still want separation between the plots, I pass a linebreak as the title, like so:

```{r}
library(dygraphs)
lungDeaths <- cbind(mdeaths, fdeaths)

res <- lapply(1:2, function(i) {
    dygraph(lungDeaths[, i], main = "<br>") %>%
        dyOptions(titleHeight = 50) %>%
        dyCSS("dygraph.css")
    })
htmltools::tagList(res)
```

While this does work to add spacing, I'd prefer to avoid external CSS if at all possible. Not to mention, it does not allow you to add any other objects (like text or a horizontal rule) in between the plots themselves. Is there a way to manually add these objects between each iteration of the function call?

Edit: So based on an answer below, we can also add in a break between each iteration like so:

```{r}
library(dygraphs)
lungDeaths <- cbind(mdeaths, fdeaths)

res <- lapply(1:2, function(i) {
    dygraph(lungDeaths[, i])

    })

invisible(lapply(1:2, function(i) {
    if (!exists("l")) {
        l <<- list()
        }

        l[[i]] <<- htmltools::tags$br() 
    }))

out <- c(rbind(l, res))

htmltools::tagList(out)

```

This seems pretty good, although I'd be interested to hear some other thoughts.

Upvotes: 4

Views: 839

Answers (1)

Thomas Kiehne
Thomas Kiehne

Reputation: 61

I'm not greatly familiar with tagLists, but it would seem that you could interleave markup/tags containing your additional rules, spacing, text, etc. with the dygraph list, e.g.:

space <- list(htmltools::tags$h1("Title"), 
              htmltools::tags$h2("Header text"))
out <- c(rbind(space, res))
htmltools::tagList(out)

Then each set of tags in the list will be rendered in turn.

Upvotes: 2

Related Questions