R/shing:仅在有光泽的应用程序中需要时渲染绘图元素



我目前正在编写一个闪亮的应用程序。我想减少绘图的渲染时间(因为初始化绘图需要很长时间)。假设我想动态地渲染一个图,例如

plot(x=1:10)

plot不会是我将在闪亮的应用程序中使用的功能。)

现在我想把绘图分成几个部分,在这里:

plot(x=NA, y=NA, xlim=c(0,10), ylim=c(0,10))
points(x=1:10)

其中CCD_ 2将在闪亮的应用程序中花费非常长的时间来渲染,而CCD_。我需要一个只有在第一次加载应用程序时才会执行plot(x=NA, y=NA, xlim=c(0,10), ylim=c(0,10))的过程,然后将自下而上构建绘图(在绘图中添加点、线等)。有人知道如何将其写入应用程序吗?这里的问题是,我将在闪亮的应用程序中使用的绘图功能不会返回任何内容。绘图功能基于基本graphics系统(不在ggplot2上,也不在lattice上)。

以下是这样一个应用程序的最小工作示例:

library(shiny)
shinyAPP <- function() {
ui <- fluidPage(
    sidebarPanel(),
    mainPanel(
        plotOutput("plotPoints"))
)
server <- function(input, output, session) {
    output$plotPoints <- renderPlot(
        plot(x=1:10)
        ## this needs to be replaced with:
        ##plot(x=NA, y=NA, xlim=c(0,10), ylim=c(0,10))
        ##points(x=1:10)
    )
}
app <- list(ui = ui, server = server)
runApp(app)
}
shinyAPP()

非常感谢!

所以也许可以试试grDevices,比如这里:

服务器.R:

library("shiny")
library("grDevices")
data(iris)
plot(x=NA, y=NA, xlim=c(0,10), ylim=c(0,10))
p <- recordPlot()
function(input, output, session) {
    output$plotPoints <- renderPlot({
        replayPlot(p)
        points(1:input$ile)
    })
}

和ui。R:

library(shiny)
fluidPage(
        sidebarPanel(
            sliderInput("ile", min=1, max=10, label="", value=5)
        ),
        mainPanel(
            plotOutput("plotPoints"))
    )

您说过不会使用plot,但使用什么很重要。例如,对于ggplot,您可以这样做(参见reactive):

ui.R:

library(shiny)
fluidPage(
        sidebarPanel(
            sliderInput("ile", min=1, max=10, label="", value=5)
        ),
        mainPanel(
            plotOutput("plotPoints"))
    )

服务器.R

library("shiny")
library("ggplot2")
data(iris)
function(input, output, session) {
    wyk <- reactive({ggplot(iris)})
    output$plotPoints <- renderPlot(
        wyk() + geom_point(aes(x=Sepal.Length, y=Sepal.Width), col=input$ile)
    )
}

如果我理解你的问题,这里有一个小技巧应该会奏效。然而,这不是R,只是一个快速的解决方案。

测试/ui.R:

fluidPage(
    sidebarPanel(
        actionButton("trickButton","Useless"),
        sliderInput("something", min=1, max=5, label="Useful", value=5)
    ),
    mainPanel(
        plotOutput("plotPoints")
    )
)

测试/服务器.R:

data(iris)
myData <<- NULL
superHeavyLoad <- function() {
    print("That is super heavy !")
    myData <<- iris
}
function(input, output, session) {
    observe({
        if (!input$trickButton)
            superHeavyLoad()
    })
    output$plotPoints <- renderPlot(
        plot(myData[,1:as.numeric(input$something)])
    )
}

现在,在您的R控制台上:

require(shiny)
runApp("test")
Listening on http://127.0.0.1:7175
[1] "That is super heavy !"

无论你做什么,你都不会再更新超重的部分。现在,根据我的理解,你所做的是将你的处理分为繁重的一次性功能和反应性功能。这是一种(不太漂亮的)方式;-)

关于它的工作原理:这一切都在我们添加的按钮中。observe函数将在每次与按钮交互时调用,另外在服务器启动时调用。if(!input$trickButton)声明我们只是在服务器启动(因为按钮没有值)。您也可以使用renderUI机制隐藏这个无用的按钮。

相关内容

最新更新