0

I am trying to create an R Markdown document that includes a tabset of interactive plots created using ggplotly. My goal is to generate these plots using loops like for, lapply, or purrr::map. While this approach successfully creates the tabs, the plots all appear at the last tab, all at once. However, when I remove ggplotly and use only ggplot, the code works fine. Similarly, when I create separate chunks for individual figures without using a loop, the plots are correctly generated in their respective tabs. What would be the underlying logic here to get the plots each for each tab?

I tried the answer from Interactive ggplotly graph is not plotted from inside for loop in Rmd file in R among others. I tried plot.new() but that removed the plots even from the last tab.

## **Count Distribution** {.tabset}
```{r, results='asis', warning=FALSE}
# List of dataframes for the first tabset
library(ggplot2)
library(reshape2)
library(plotly)
hist_func <- function(matrix) {
  hist_plot <- ggplot(melt(as.data.frame(matrix))) +
                        geom_line(stat = 'density', aes(x = value, ..scaled.., colour = variable)) +
                        labs(x = NULL) + theme(legend.position = 'right') + scale_x_log10()

  return(hist_plot)
}

# Set seed 
set.seed(42)

# Generate random gene count matrix
c1 <- matrix(sample(0:10000, 10 * 1000, replace = TRUE), nrow = 10)
c2 <- matrix(sample(0:10000, 10 * 1000, replace = TRUE), nrow = 10)
c3 <- matrix(sample(0:10000, 10 * 1000, replace = TRUE), nrow = 10)
c4 <- matrix(sample(0:10000, 10 * 1000, replace = TRUE), nrow = 10)
c5 <- matrix(sample(0:10000, 10 * 1000, replace = TRUE), nrow = 10)

# List of dataframes for the  tabset
dataframes_tab1 <- list(counts = c1, rawlog2 = c2, TMM = c3, DESEQ2 = c4, VOOM = c5)

plt <- htmltools::tagList()

# Generate tabset content using loop
plotlist=list()
for (i in seq_along(dataframes_tab1)) {
  
  df_name <- names(dataframes_tab1)[i]
  plotlist[[i]] <- ggplotly(hist_func(dataframes_tab1[[df_name]]))
  cat(paste('### ', df_name, '\n \n'))
  cat(' \n')

  # trying multiple approaches
  plt[[i]] <- as.widget(ggplotly(plotlist[[i]]))
  
  # to check if either method works #as taglist or without
  plotlist[[i]]
  plt[[i]]
  cat(' \n\n')
}
```
stefan
  • 90,330
  • 6
  • 25
  • 51

1 Answers1

1

Adapting this answer from me to your case you could achieve your desired result like so.

First, as you want one chart per tab it is not necessary to create a list. Instead you can directly print your chart by wrapping in print(htmltools::tagList(...)). Second, the important part in my approach to add an initialization step to add the plotly JS dependencies needed to render the charts.

Note: I stripped down your example data to make it more minimal.

---
title: "Untitled"
output: html_document
date: "2023-08-31"
---

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

```{r, include=FALSE}
library(ggplot2)
library(reshape2)
library(plotly)
```

## **Count Distribution** {.tabset}

```{r}
hist_func <- function(matrix) {
  hist_plot <- ggplot(melt(as.data.frame(matrix))) +
    geom_line(stat = "density", aes(x = value, ..scaled.., colour = variable)) +
    labs(x = NULL) +
    theme(legend.position = "right") +
    scale_x_log10()

  return(hist_plot)
}
```

```{r}
# Set seed
set.seed(42)

# Generate random gene count matrix
c1 <- matrix(sample(seq(100), 100, replace = TRUE), nrow = 10)
c2 <- matrix(sample(seq(100), 100, replace = TRUE), nrow = 10)
c3 <- matrix(sample(seq(100), 100, replace = TRUE), nrow = 10)
c4 <- matrix(sample(seq(100), 100, replace = TRUE), nrow = 10)
c5 <- matrix(sample(seq(100), 100, replace = TRUE), nrow = 10)

# List of dataframes for the  tabset
dataframes_tab1 <- list(counts = c1, rawlog2 = c2, TMM = c3, DESEQ2 = c4, VOOM = c5)
```

```{r include=FALSE}
# Init step to include the JS dependencies
plot_ly()
```

```{r, results='asis', warning=FALSE}
for (i in names(dataframes_tab1)) {
  cat(paste("### ", i, "\n \n"))
  cat("\n")
  print(
    htmltools::tagList(
      ggplotly(hist_func(dataframes_tab1[[i]]))
    )
  )
  cat("\n\n")
}
```

enter image description here

stefan
  • 90,330
  • 6
  • 25
  • 51