使用闪亮动态地将绘图添加到网页

Posted

技术标签:

【中文标题】使用闪亮动态地将绘图添加到网页【英文标题】:dynamically add plots to web page using shiny 【发布时间】:2013-03-30 08:08:36 【问题描述】:

我想创建一个使用闪亮的应用程序,该应用程序可以动态地将绘图添加到页面。可能是 10 个地块,也可能只有一个地块。我在闪亮的主页中使用this tutorial 来获取动态用户界面。

这是一个简化的例子。 函数showme 正在绘制图表

server.r

shinyServer(function(input, output) 
  # Create an environment for storing data
  symbol_env <- new.env()
  # Make a chart for a symbol, with the settings from the inputs
  make_chart <- function(symbol) 
    showme(symbol)
  

  display <- c("1083484" , "1101732")

  output$MyList <- renderUi( 
    for (i in i:nrow(display))
       renderPlot(make_chart(display[i]))
    )
)

ui.r

shinyUI(pageWithSidebar(
  headerPanel("My Plots !"),
  sidebarPanel(
    wellPanel(
      p(strong("Scan1"))))
 ,mainPanel(
      uiOutput("MyList")
)))

我收到以下错误

Listening on port 8100
Error in .subset2(x, "impl")$defineOutput(name, value, deparse(substitute(value))) : 
  Unexpected character output for display

如果不是这样 - 我将不胜感激任何指导。 谢谢。

> sessionInfo()
R version 2.15.3 (2013-03-01)
Platform: i386-w64-mingw32/i386 (32-bit)

【问题讨论】:

【参考方案1】:

也许 Winston Chang 的这个例子是有帮助的:

Shiny example app with dynamic number of plots

这里是完整的例子,以防万一链接旋转:

server.R

max_plots <- 5

shinyServer(function(input, output) 

# Insert the right number of plot output objects into the web page
output$plots <- renderUI(
  plot_output_list <- lapply(1:input$n, function(i) 
     plotname <- paste("plot", i, sep="")
     plotOutput(plotname, height = 280, width = 250)
   )

   # Convert the list to a tagList - this is necessary for the list of items
   # to display properly.
   do.call(tagList, plot_output_list)
)

# Call renderPlot for each one. Plots are only actually generated when they
# are visible on the web page.
for (i in 1:max_plots) 
    # Need local so that each item gets its own number. Without it, the value
    # of i in the renderPlot() will be the same across all instances, because
    # of when the expression is evaluated.
    local(
        my_i <- i
        plotname <- paste("plot", my_i, sep="")

        output[[plotname]] <- renderPlot(
        plot(1:my_i, 1:my_i, xlim = c(1, max_plots), ylim = c(1, max_plots), main = paste("1:", my_i, ".  n is ", input$n, sep = ""))
        )
    )

)

ui.R

shinyUI(pageWithSidebar(

  headerPanel("Dynamic number of plots"),

    sidebarPanel(
      sliderInput("n", "Number of plots", value=1, min=1, max=5)
    ),

    mainPanel(
      uiOutput("plots") # This is the dynamic UI for the plots
    )
))

【讨论】:

谢谢,这就是我要找的。我设法获得了绘制的绘图的动态列表,但是,我想打印出一个对象列表 - 每个对象都包含一个标题、一个绘图和一个表格。你知道我该怎么做吗? 您的意思是 a) 对于每个选定的对象,您要绘制所有三件事(标题、绘图和表格),或者 b) 对于每个选定的对象,然后您要选择其中的哪一个三个来绘制(或者你的意思是别的)? a - 对于每个对象,我想要一个标题、一个图和一个汇总表。动态 UI 应该是某种容器,而不仅仅是一个情节。我尝试使用renderTable 将表格添加到标记列表和输出中,但它只显示添加的最后一个 - 在我的情况下,表格。 嗯,这似乎不适用于 ggplot,有什么想法吗? @RahulSavani:你能把max_plots 设为一个反应值而不是硬编码吗?谢谢【参考方案2】:

要回答上面评论中关于如何动态返回对象列表(例如,绘图、表格和文本)的问题,您可以在renderUI 然后在 for 循环中匹配适当的渲染函数。例如:

max_plots <- 5

shinyServer(function(input, output) 

# Insert the right number of plot output objects into the web page
output$plots <- renderUI(
  plot_output_list <- lapply(1:input$n, function(i) 
     plotname <- paste("plot", i, sep="")
     plottitle <- paste("plottitle", i, sep="")
     tablename <- paste("tablename", i, sep="")
     tags$div(class = "group-output",
       textOutput(plottitle, container = h3),
       plotOutput(plotname, height = 280, width = 250),
       tableOutput(tablename)
     )
   )

   # Convert the list to a tagList - this is necessary for the list of items
   # to display properly.
   do.call(tagList, plot_output_list)
)

# Call renderPlot for each one. Plots are only actually generated when they
# are visible on the web page.
for (i in 1:max_plots) 
    # Need local so that each item gets its own number. Without it, the value
    # of i in the renderPlot() will be the same across all instances, because
    # of when the expression is evaluated.
    local(
        my_i <- i
        plotname <- paste("plot", my_i, sep="")
        plottitle <- paste("plottitle", my_i, sep="")
        tablename <- paste("tablename", my_i, sep="")

        output[[plotname]] <- renderPlot(
        plot(1:my_i, 1:my_i, xlim = c(1, max_plots), ylim = c(1, max_plots), main = paste("1:", my_i, ".  n is ", input$n, sep = ""))
        )
        output[[plottitle]] <- renderText(paste("1:", my_i, ".  n is ", input$n, sep = "")
        )
        output[[tablename]] <- renderTable(table(x = 1:my_i, y = 1:my_i)
        )
    )

)

希望对你有帮助!

【讨论】:

【参考方案3】:

使用闪亮动态添加 N 个图:

runApp(
list(
ui = fluidPage(
  headerPanel('Tittle'),

  sidebarPanel(
    fileInput('file1', 'Choose File:'),
    textInput("target", label="Target", value="Choose target"),
    actionButton("addButton", "Go!"),
    p('The button start the code server'),
    p("This is UI")

  ),

  mainPanel(

    uiOutput("plots")
  )),
#SERVER
server = function(input, output)      
  dataset <- eventReactive(input$addButton, 

    #Obtain the file and textinput
    inFile <- input$file1
    df <- read.csv(inFile$datapath)
    df$target <- input$target
    return(df)

  )

  output$plots <- renderUI(


    df <- dataset()
    n <- df$target[1]

    plot_output_list <- lapply(1:n, function(i) 

      plotname <- paste("plot", i, sep="")
      plotOutput(plotname, height = 580, width = 550)


    )


    do.call(tagList, plot_output_list)


  )
  observe(             

    for (i in 1:length()) 
      local( 


        plotname <- paste("plot", i, sep="")

        output[[plotname]] <- renderPlot(

          #function_plot is the function generate plot
          function_plot()

        )
      )#endlocal
    

  )

  )
)

https://github.com/ericbellet/recomendacion-modelos/blob/master/shiny/generate_rocSHINY.R

【讨论】:

以上是关于使用闪亮动态地将绘图添加到网页的主要内容,如果未能解决你的问题,请参考以下文章

根据窗口大小动态调整闪亮绘图输出的高度和/或宽度

动态创建带有闪亮绘图的选项卡,而无需重新创建现有选项卡

如何在闪亮的直方图中动态添加和删除覆盖

使用装饰器动态地将方法添加到类中

动态地将selectInput值从UI传递到R中的Server代码

如何动态地将组件作为子组件添加到指令中?