R Shiny无法显示预期绘图,关闭应用后才在RStudio显示的问题
问题:Shiny应用中无法显示collapsibleTree绘图,关闭后才在RStudio绘图区出现
我是R Shiny新手,想要开发一款读取Excel文件、处理数据框并根据指定ID输出绘图的应用。提供的代码在非Shiny环境下可正常运行,但在Shiny应用中无法显示预期绘图,关闭应用后绘图才会出现在RStudio的绘图区域,请问我哪里操作有误?
原代码
library(shiny) library(readxl) library(ggenealogy) library(ggplot2) library(collapsibleTree) datos = read_xlsx("file.xlsx", sheet = 1) '%!in%' = function(x,y)!('%in%'(x,y)) ui <- fluidPage( titlePanel("Buscar genealogía"), sidebarLayout( sidebarPanel( helpText("Search dendrogram for a given ID"), textInput("bidi", label = "Write ID:", value = "PL1804160067"), ), mainPanel( plotOutput("grafica") ) ) ) server <- function(input, output) { output$grafica <- renderPlot({ grafico = plotAncDes(input$bidi, datos, 9, 9) datos2 = grafico$data if ("ancestor" %in% datos2$type){ ancestros = datos2[datos2$type == "ancestor",] n_ancestros = nrow(ancestros) generaciones = sort(unique(datos2$genside)) rows_final = nrow(datos2[datos2$genside == 1,]) final = data.frame(matrix(ncol = length(generaciones), nrow = rows_final)) colnames(final) = generaciones n_generaciones = length(which(generaciones > 0)) for (n_ancestro in 1:ncol(final)){ if (as.numeric(colnames(final)[n_ancestro]) < 0){ final[, n_ancestro] = datos2$label[which(datos2$genside == colnames(final)[n_ancestro])] } } final[, "0"] = input$bidi hijos = getChild(input$bidi, datos) final[, "1"] = hijos generacion = 1 if (max(generaciones) - generacion > 0){ quedan_generaciones = TRUE } else { quedan_generaciones = FALSE } while (quedan_generaciones){ for (muestra in unique(final[, as.character(generacion)])){ nuevos_hijos = getChild(muestra, datos) if (length(nuevos_hijos > 0)){ subdataset = final[which(final[, as.character(generacion)] == muestra),] fila_copiar = subdataset for (i in 1:(length(nuevos_hijos) -1)){ subdataset = rbind(subdataset, fila_copiar) } subdataset[, as.character(generacion + 1)] = nuevos_hijos final = final[-which(final[, as.character(generacion)] == muestra),] final = rbind(final, subdataset) } } generacion = generacion + 1 if (generacion > max(generaciones)){ quedan_generaciones = FALSE } } } if ("ancestor" %!in% datos2$type){ generaciones = sort(unique(datos2$genside)) rows_final = nrow(datos2[datos2$genside == 1,]) final = data.frame(matrix(ncol = length(generaciones), nrow = rows_final)) colnames(final) = generaciones n_generaciones = length(which(generaciones > 0)) final[, "0"] = input$bidi hijos = getChild(input$bidi, datos) final[, "1"] = hijos generacion = 1 if (max(generaciones) - generacion > 0){ quedan_generaciones = TRUE } else { quedan_generaciones = FALSE } while (quedan_generaciones){ for (muestra in unique(final[, as.character(generacion)])){ nuevos_hijos = getChild(muestra, datos) if (length(nuevos_hijos > 0)){ subdataset = final[which(final[, as.character(generacion)] == muestra),] fila_copiar = subdataset for (i in 1:(length(nuevos_hijos) - 1)){ subdataset = rbind(subdataset, fila_copiar) } subdataset[, as.character(generacion + 1)] = nuevos_hijos final = final[-which(final[, as.character(generacion)] == muestra),] final = rbind(final, subdataset) } } generacion = generacion + 1 if (generacion > max(generaciones)){ quedan_generaciones = FALSE } } } collapsibleTree(final, hierarchy = colnames(final)) }) } shinyApp(ui, server)
问题原因与解决方案
核心问题
collapsibleTree()返回的是HTML交互式控件(htmlwidgets对象),而非传统的R图形对象(如ggplot2或基础绘图)。你当前使用的renderPlot()和plotOutput()是专门用于渲染传统R图形的,无法正确处理htmlwidgets类型的输出,导致绘图无法在Shiny界面显示,只能在关闭应用后输出到RStudio的绘图区。
修改步骤
- UI端:将
plotOutput("grafica")替换为htmlOutput("grafica")(或使用collapsibleTreeOutput("grafica"),两者效果一致)。 - Server端:将
renderPlot()替换为renderUI(),确保返回collapsibleTree生成的对象。
修改后的完整代码
library(shiny) library(readxl) library(ggenealogy) library(ggplot2) library(collapsibleTree) datos = read_xlsx("file.xlsx", sheet = 1) '%!in%' = function(x,y)!('%in%'(x,y)) ui <- fluidPage( titlePanel("Buscar genealogía"), sidebarLayout( sidebarPanel( helpText("Search dendrogram for a given ID"), textInput("bidi", label = "Write ID:", value = "PL1804160067"), ), mainPanel( # 替换为htmlOutput htmlOutput("grafica") ) ) ) server <- function(input, output) { # 替换为renderUI output$grafica <- renderUI({ grafico = plotAncDes(input$bidi, datos, 9, 9) datos2 = grafico$data if ("ancestor" %in% datos2$type){ ancestros = datos2[datos2$type == "ancestor",] n_ancestros = nrow(ancestros) generaciones = sort(unique(datos2$genside)) rows_final = nrow(datos2[datos2$genside == 1,]) final = data.frame(matrix(ncol = length(generaciones), nrow = rows_final)) colnames(final) = generaciones n_generaciones = length(which(generaciones > 0)) for (n_ancestro in 1:ncol(final)){ if (as.numeric(colnames(final)[n_ancestro]) < 0){ final[, n_ancestro] = datos2$label[which(datos2$genside == colnames(final)[n_ancestro])] } } final[, "0"] = input$bidi hijos = getChild(input$bidi, datos) final[, "1"] = hijos generacion = 1 if (max(generaciones) - generacion > 0){ quedan_generaciones = TRUE } else { quedan_generaciones = FALSE } while (quedan_generaciones){ for (muestra in unique(final[, as.character(generacion)])){ nuevos_hijos = getChild(muestra, datos) if (length(nuevos_hijos > 0)){ subdataset = final[which(final[, as.character(generacion)] == muestra),] fila_copiar = subdataset for (i in 1:(length(nuevos_hijos) -1)){ subdataset = rbind(subdataset, fila_copiar) } subdataset[, as.character(generacion + 1)] = nuevos_hijos final = final[-which(final[, as.character(generacion)] == muestra),] final = rbind(final, subdataset) } } generacion = generacion + 1 if (generacion > max(generaciones)){ quedan_generaciones = FALSE } } } if ("ancestor" %!in% datos2$type){ generaciones = sort(unique(datos2$genside)) rows_final = nrow(datos2[datos2$genside == 1,]) final = data.frame(matrix(ncol = length(generaciones), nrow = rows_final)) colnames(final) = generaciones n_generaciones = length(which(generaciones > 0)) final[, "0"] = input$bidi hijos = getChild(input$bidi, datos) final[, "1"] = hijos generacion = 1 if (max(generaciones) - generacion > 0){ quedan_generaciones = TRUE } else { quedan_generaciones = FALSE } while (quedan_generaciones){ for (muestra in unique(final[, as.character(generacion)])){ nuevos_hijos = getChild(muestra, datos) if (length(nuevos_hijos > 0)){ subdataset = final[which(final[, as.character(generacion)] == muestra),] fila_copiar = subdataset for (i in 1:(length(nuevos_hijos) - 1)){ subdataset = rbind(subdataset, fila_copiar) } subdataset[, as.character(generacion + 1)] = nuevos_hijos final = final[-which(final[, as.character(generacion)] == muestra),] final = rbind(final, subdataset) } } generacion = generacion + 1 if (generacion > max(generaciones)){ quedan_generaciones = FALSE } } } # 返回collapsibleTree对象 collapsibleTree(final, hierarchy = colnames(final)) }) } shinyApp(ui, server)
额外说明
如果偏好使用专门的控件,也可以将UI端的htmlOutput替换为collapsibleTreeOutput("grafica"),Server端的renderUI替换为renderCollapsibleTree,功能完全一致。
内容的提问来源于stack exchange,提问作者anttphy
相关产品推荐
相关产品推荐

