Obwohl beide Antworten auf diese Frage sind sehr gut, ich wollte ein anderes füge mit shiny modules. Das folgende Modul verwendet eine Plotfunktion und eine reaktive Version seiner Argumente als Eingaben. Am Ende wird do.call(plotfun, args())
verwendet, um das Diagramm zu erstellen.
library(shiny)
cachePlot <- function(input, output, session, plotfun, args, width = 480, height = 480,
dir = tempdir(), prefix = "cachedplot", deleteonexit = TRUE){
hash <- function(args) digest::digest(args)
output$plot <- renderImage({
args <- args()
if (!is.list(args)) args <- list(args)
imgpath <- file.path(dir, paste0(prefix, "-", hash(args), ".png"))
if(!file.exists(imgpath)){
png(imgpath, width = width, height = height)
do.call(plotfun, args)
dev.off()
}
list(src = imgpath)
}, deleteFile = FALSE)
if (deleteonexit) session$onSessionEnded(function(){
imgfiles <- list.files(tempdir(), pattern = prefix, full.names = TRUE)
file.remove(imgfiles)
})
}
cachePlotUI <- function(id){
ns <- NS(id)
imageOutput(ns("plot"))
}
Wie wir sehen können, löscht das Modul das Bild erstellt Dateien, wenn die Option benötigt und gibt einen benutzerdefinierten Cache-Verzeichnis, falls persistenten Cache benötigt wird, verwendet werden (wie es in meinem eigentlichen usecase ist).
Für ein Anwendungsbeispiel werde ich das hist(faithful[, 2])
Beispiel wie Stedy verwenden.
histfaithful <- function(bins, col){
message("calling histfaithful with args ", bins, " and ", col)
x <- faithful[, 2]
bins <- seq(min(x), max(x), length.out = bins + 1)
hist(x, breaks = bins, col = col, border = 'white')
}
shinyApp(
ui = fluidPage(
inputPanel(
sliderInput("bins", "bins", 5, 30, 10, 1),
selectInput("col", "color", c("blue", "red"))
),
cachePlotUI("cachedPlot")
),
server = function(input, output, session){
callModule(
cachePlot, "cachedPlot", histfaithful,
args = reactive(list(bins = input$bins, col = input$col))
)
}
)
Siehe das Beispiel unter '? RenderImage', es könnte Ihnen einige Ideen geben. Grundsätzlich möchten Sie eine Memo-Plot-Funktion, die eine PNG-Datei zurückgibt, denke ich; und benutze renderImage, um diese Memo-Funktion aufzurufen. –
Danke Joe. Irgendwelche Ideen, wie wir glänzen können, um statische Bilder automatisch zu skalieren, die wir mit renderImage rendern. – Abhi