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') } ``` 

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! I was beating my head against this and this solved it. I found so many other "solutions" for similar problems that didn't do the trick, but this one did.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.