Reputation: 187
I am a beginner to shiny and shinydashboard. Currently, I would like to have 2 different tabs that are able to generate multiple plots if the appropriate CSV file(s) are inserted.
I have functions to format users CSV files which turn them into data frames that are contained in a list. I then have another function that can plot these data frames (turn them into copy number plot). This is the simplified version of what I currently have for the dashboard...
ui <-
dashboardPage(
skin = "blue",
dashboardHeader(title = "Dashboard"),
dashboardSidebar(
sidebarMenu(
menuItem("Guide", tabName = "Guide", icon = icon("info")),
menuItem("Copy-Number-Analysis", icon = icon("dna"),
menuSubItem("Filtered-Amplicon", tabName = "Filtered-Amplicon", icon = icon("arrow-alt-circle-right")),
menuSubItem("Whole-Chromosome", tabName = "Whole-Chromosome", icon = icon("arrow-alt-circle-right"))
)
)
),
dashboardBody(
tabItems(
tabItem(tabName = "Guide",
fluidRow(box(
title = strong("How do I use this application?",style = "font-size: 160%;"),
))
),
tabItem(tabName = "Filtered-Amplicon",
fluidRow(box(
title = strong("Filtered Amplicon Copy Number Plot", style = "font-size: 160%;"),
status = "danger",
solidHeader = T,
width = 12,
fileInput("file1", h4("Input your file(s) in csv format!"),
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv"),
multiple = TRUE
),
uiOutput("PlotVisualizeAmplicon") #Visualize plot
))),
tabItem(tabName = "Whole-Chromosome",
fluidRow(box(
title = strong("Whole Chromosome Copy Number Plot", style = "font-size: 160%;"),
status = "danger",
solidHeader = T,
width = 12,
fileInput("file2", h4("Input your file(s) in csv format!"),
accept = c(
"text/csv",
"text/comma-separated-values,text/plain",
".csv"),
multiple = TRUE
),
uiOutput("PlotVisualizeWhole") #Visualize plot
))
)
)
)
)
)
server <- function(input, output) {
#Set the number of max input
maxPlot <- 100
#AMPLICON PLOT
#Data Input
dataPlotInput2 <- reactive({
if(is.null(input$file1)){return()}
#Input CSVs
files_name <- as.list(rep(NA, length(input$file1$datapath)))
for (i in 1:length(input$file1$datapath)){
files_name[[i]] <- as.character(input$file1[i,4])
}
files_list <- as.list(rep(NA, length(input$file1$datapath)))
for(i in 1:length(input$file1$datapath)){
files_list[[i]] <- read_csv(
file = as.character(files_name[[i]]))%>%
select(1:5)
}
names(files_list) <- files_name
#Copy Number analysis
files_formated <- format_all(files_list)
comparison_tbl_Amplicon <- ref_compare_all(files_formated, reference = reference1)
comparison_tbl_Amplicon
})
# Produce plot(s)
for (i in 1:maxPlot) {
local({
my_i <- i
plotnameAmplicon <- paste("plot", my_i, sep="")
output[[plotnameAmplicon]] <- renderPlot({
plot_aneuploid(dataPlotInput2()[[my_i]], size = 2) + ggtitle(as.character(input$file1[my_i,1]))
})
})
}
output$PlotVisualizeAmplicon <- renderUI({
if(is.null(input$file1)){return()}
FileNumber <- nrow(input$file1)
plot_output_list_Amplicon <- lapply(1:FileNumber, function(i) {
plotnameAmplicon <- paste("plot", i, sep="")
plotOutput(plotnameAmplicon, width = "100%", height = "400px")
})
do.call(tagList, plot_output_list_Amplicon)
})
##WHOLE CHROMOSOME PLOT
#Data input
dataPlotInput3 <- reactive({
if(is.null(input$file2)){return()}
#Input CSVs
files_name <- as.list(rep(NA, length(input$file2$datapath)))
for (i in 1:length(input$file2$datapath)){
files_name[[i]] <- as.character(input$file2[i,4])
}
files_list <- as.list(rep(NA, length(input$file2$datapath)))
for(i in 1:length(input$file2$datapath)){
files_list[[i]] <- read_csv(
file = as.character(files_name[[i]]))%>%
select(1:5)
}
names(files_list) <- files_name
#Copy Number analysis
files_formated <- format_all(files_list)
comparison_tbl_Whole <- ref_compare_whole_chr_all(files_formated, reference = reference1)
comparison_tbl_Whole
})
#Produce plot(s)
for (i in 1:maxPlot) {
local({
my_j <- i
plotnameWhole <- paste("plot", my_j, sep="")
output[[plotnameWhole]] <- renderPlot({
plot_aneuploid_whole_chr(dataPlotInput3()[[my_j]], size = 2) + ggtitle(as.character(input$file2[my_j,1]))
})
})
}
output$PlotVisualizeWhole <- renderUI({
if(is.null(input$file2)){return()}
FileNumber <- nrow(input$file2)
plot_output_list_Whole <- lapply(1:FileNumber, function(i) {
plotnameWhole <- paste("plot", i, sep="")
plotOutput(plotnameWhole, width = "100%", height = "400px")
})
do.call(tagList, plot_output_list_Whole)
})
}
My final goal is to able to produce different plots in the two tabs that I have which should look something like this with me being able to use them alternately...
I am currently unable to simultaneously generate both plots in different tabs. I am only able to generate them only if the other tab does not exist (I turn the unused tabs into comments to generate these images).
The way I visualize the plot is by having uiOutput
in the ui function. I generated my plots inside output[[plotnameAmplicon]]
and output[[plotnameWhole]]
with renderPlot. I then use renderUi
to show all the plots. This method works only when the other plotting tab does not exist. If I ran the code that I currently have, for some reason the results of tab2 appear in tab1 and I cannot generate tab 1 plots. Is there a way to fix this. Any suggestion to improve the plotting logic is also highly appreciated as I am new to shiny and shinydashboard.
Upvotes: 0
Views: 36
Reputation: 187
I have found a solution. By encapsulating renderPlot inside renderUi and by giving a different variable name for renderPlot (silly mistake by me), I was able to produce the desired output.
output$PlotVisualizeWhole <- renderUI({
if(is.null(input$file2)){return()}
FileNumber <- nrow(input$file2)
plot_output_list_Whole <- lapply(1:FileNumber, function(i) {
plotnameWhole <- paste("plotwhole", i, sep="")
output[[plotnameWhole]] <- renderPlot({
plot_aneuploid_whole_chr(dataPlotInput3()[[i]], size = 2) + ggtitle(as.character(input$file2[i,1]))})
plotDownload <- paste("Downloaded", i, sep = "")
plotOutput(plotnameWhole, width = "100%", height = "400px")
})
do.call(tagList, plot_output_list_Whole)
})
Upvotes: 0