r - 渲染绘图列表时出现 renderPlot 问题
问题描述
我正在编写一个 R 闪亮的应用程序,它应该允许用户创建一些数据的可定制图。这个想法是我的应用程序提供了一个“创建新情节”按钮,它可以渲染情节并将其存储在反应式中。renderUI 函数“监视”此列表并呈现该响应式中的所有绘图。
我发现了几个相关的问题r-markdown-shiny-renderplot-list-of-plots-from-lapply或shiny-r-renderplots-on-the-fly但这对我的情况并没有真正的帮助。我希望我没有在某个地方错过一个好的答案(我认为这是因为我认为这不是一个罕见的用例)。
实施时,我注意到一个奇怪的行为:当只有一个情节要显示时,一切正常。但是,当我有 n (n>1) 个绘图时,应用程序只显示 n 次绘图 n,而不是渲染绘图 1、绘图 2、...、绘图 n。
请参阅下面的示例应用程序。我通过让用户选择要显示的绘图数量来简化问题。然后,renderUI 函数有一个循环,在变量 p 中创建这些图,然后调用 renderPlot(p)。我假设闪亮会进行一些缓存,并且由于某种原因无法识别循环中的 p 变化?!
我通过用 do.call("renderPlot", list(expr = p) 替换 renderPlot(p) 找到了一种解决方法。这可以完成工作,但我仍然很想知道为什么直接 renderPlot 不起作用。
这是我的示例应用程序:
library(shiny)
library(ggplot2)
# Define UI
ui <- shinyUI(fluidPage(
titlePanel("renderPlot Test"),
sidebarLayout(
sidebarPanel(
numericInput(inputId = "n", label = "Number of Plots", value = 1L, min = 1L, max = 5L, step = 1L),
checkboxInput(inputId = "use_do.call", label = "use 'do.call'", value = FALSE)
),
mainPanel(
uiOutput("show_plots")
)
)
))
# Define server logic
server <- shinyServer(function(input, output) {
output$show_plots <- renderUI({
ui <- tags$div(tags$h4("Plots"))
for( i in 1:input$n ) {
p <- ggplot() + ggtitle(paste("plot", i))
if( input$use_do.call ) { # this works
ui <- tagAppendChild(ui, do.call("renderPlot", args=list(expr=p, width = 200, height = 200)))
} else { # this doesn't ...
ui <- tagAppendChild(ui, renderPlot(p, width = 200, height = 200))
}
}
return(ui)
})
})
# Run the application
shinyApp(ui = ui, server = server)
解决方案
我同意@JonMinton,我也遇到了同样的问题。我发现当我重用相同的变量来保存绘图并渲染它们(例如你对 p 所做的事情)时,绘图会被下一个绘图覆盖,并且只有最终绘图会像你说的那样被复制 n 次。
为了解决这个问题,我为每个地块定义了一个新变量,这对于您的项目可能不可持续,但它是一种解决方法。
推荐阅读
- reactjs - 在 TypeScript 中从 React.router.dom 添加到 props.location.state 的类型
- python - 在不同场景中将带参数的函数传递给装饰器之间的区别
- postgresql - PostgreSQL:使用同义词字典作为表
- c# - 具有共享函数的 C# Parallel.ForEach 抛出 IndexOutOfRangeException
- amazon-web-services - nifi 通过 aws 帐户重定向
- javascript - 快速切换标签时传递的相同消息不止一次:Chrome 扩展问题
- php - 将集合转换为刀片中的列表
- .net - ProcessStartInfo.ArgumentList 是否容易受到操作系统命令注入的影响?
- python - 如何用随机数量的项目填充 XML 文件
- reactjs - React Todo 与 Firebase 将动作移动到 redux