mirror of
https://github.com/rstudio/shiny.git
synced 2026-01-13 17:08:05 -05:00
* Close #3626: use ragg::agg_png over Cairo::CairoPNG if available * Update documentation
248 lines
8.8 KiB
R
248 lines
8.8 KiB
R
% Generated by roxygen2: do not edit by hand
|
|
% Please edit documentation in R/render-cached-plot.R
|
|
\name{renderCachedPlot}
|
|
\alias{renderCachedPlot}
|
|
\title{Plot output with cached images}
|
|
\usage{
|
|
renderCachedPlot(
|
|
expr,
|
|
cacheKeyExpr,
|
|
sizePolicy = sizeGrowthRatio(width = 400, height = 400, growthRate = 1.2),
|
|
res = 72,
|
|
cache = "app",
|
|
...,
|
|
alt = "Plot object",
|
|
outputArgs = list(),
|
|
width = NULL,
|
|
height = NULL
|
|
)
|
|
}
|
|
\arguments{
|
|
\item{expr}{An expression that generates a plot.}
|
|
|
|
\item{cacheKeyExpr}{An expression that returns a cache key. This key should
|
|
be a unique identifier for a plot: the assumption is that if the cache key
|
|
is the same, then the plot will be the same.}
|
|
|
|
\item{sizePolicy}{A function that takes two arguments, \code{width} and
|
|
\code{height}, and returns a list with \code{width} and \code{height}. The
|
|
purpose is to round the actual pixel dimensions from the browser to some
|
|
other dimensions, so that this will not generate and cache images of every
|
|
possible pixel dimension. See \code{\link[=sizeGrowthRatio]{sizeGrowthRatio()}} for more
|
|
information on the default sizing policy.}
|
|
|
|
\item{res}{The resolution of the PNG, in pixels per inch.}
|
|
|
|
\item{cache}{The scope of the cache, or a cache object. This can be \code{"app"}
|
|
(the default), \code{"session"}, or a cache object like a
|
|
\code{\link[cachem:cache_disk]{cachem::cache_disk()}}. See the Cache Scoping section for more information.}
|
|
|
|
\item{...}{Arguments to be passed through to \code{\link[=plotPNG]{plotPNG()}}.
|
|
These can be used to set the width, height, background color, etc.}
|
|
|
|
\item{alt}{Alternate text for the HTML \verb{<img>} tag if it cannot be displayed
|
|
or viewed (i.e., the user uses a screen reader). In addition to a character
|
|
string, the value may be a reactive expression (or a function referencing
|
|
reactive values) that returns a character string. If the value is \code{NA} (the
|
|
default), then \code{ggplot2::get_alt_text()} is used to extract alt text from
|
|
ggplot objects; for other plots, \code{NA} results in alt text of "Plot object".
|
|
\code{NULL} or \code{""} is not recommended because those should be limited to
|
|
decorative images.}
|
|
|
|
\item{outputArgs}{A list of arguments to be passed through to the implicit
|
|
call to \code{\link[=plotOutput]{plotOutput()}} when \code{renderPlot} is used in an
|
|
interactive R Markdown document.}
|
|
|
|
\item{width, height}{not used. They are specified via the argument
|
|
\code{sizePolicy}.}
|
|
}
|
|
\description{
|
|
Renders a reactive plot, with plot images cached to disk. As of Shiny 1.6.0,
|
|
this is a shortcut for using \code{\link[=bindCache]{bindCache()}} with \code{\link[=renderPlot]{renderPlot()}}.
|
|
}
|
|
\details{
|
|
\code{expr} is an expression that generates a plot, similar to that in
|
|
\code{renderPlot}. Unlike with \code{renderPlot}, this expression does not
|
|
take reactive dependencies. It is re-executed only when the cache key
|
|
changes.
|
|
|
|
\code{cacheKeyExpr} is an expression which, when evaluated, returns an object
|
|
which will be serialized and hashed using the \code{\link[rlang:hash]{rlang::hash()}}
|
|
function to generate a string that will be used as a cache key. This key is
|
|
used to identify the contents of the plot: if the cache key is the same as a
|
|
previous time, it assumes that the plot is the same and can be retrieved from
|
|
the cache.
|
|
|
|
This \code{cacheKeyExpr} is reactive, and so it will be re-evaluated when any
|
|
upstream reactives are invalidated. This will also trigger re-execution of
|
|
the plotting expression, \code{expr}.
|
|
|
|
The key should consist of "normal" R objects, like vectors and lists. Lists
|
|
should in turn contain other normal R objects. If the key contains
|
|
environments, external pointers, or reference objects --- or even if it has
|
|
such objects attached as attributes --- then it is possible that it will
|
|
change unpredictably even when you do not expect it to. Additionally, because
|
|
the entire key is serialized and hashed, if it contains a very large object
|
|
--- a large data set, for example --- there may be a noticeable performance
|
|
penalty.
|
|
|
|
If you face these issues with the cache key, you can work around them by
|
|
extracting out the important parts of the objects, and/or by converting them
|
|
to normal R objects before returning them. Your expression could even
|
|
serialize and hash that information in an efficient way and return a string,
|
|
which will in turn be hashed (very quickly) by the
|
|
\code{\link[rlang:hash]{rlang::hash()}} function.
|
|
|
|
Internally, the result from \code{cacheKeyExpr} is combined with the name of
|
|
the output (if you assign it to \code{output$plot1}, it will be combined
|
|
with \code{"plot1"}) to form the actual key that is used. As a result, even
|
|
if there are multiple plots that have the same \code{cacheKeyExpr}, they
|
|
will not have cache key collisions.
|
|
}
|
|
\section{Interactive plots}{
|
|
|
|
|
|
\code{renderCachedPlot} can be used to create interactive plots. See
|
|
\code{\link[=plotOutput]{plotOutput()}} for more information and examples.
|
|
}
|
|
|
|
\examples{
|
|
## Only run examples in interactive R sessions
|
|
if (interactive()) {
|
|
|
|
# A basic example that uses the default app-scoped memory cache.
|
|
# The cache will be shared among all simultaneous users of the application.
|
|
shinyApp(
|
|
fluidPage(
|
|
sidebarLayout(
|
|
sidebarPanel(
|
|
sliderInput("n", "Number of points", 4, 32, value = 8, step = 4)
|
|
),
|
|
mainPanel(plotOutput("plot"))
|
|
)
|
|
),
|
|
function(input, output, session) {
|
|
output$plot <- renderCachedPlot({
|
|
Sys.sleep(2) # Add an artificial delay
|
|
seqn <- seq_len(input$n)
|
|
plot(mtcars$wt[seqn], mtcars$mpg[seqn],
|
|
xlim = range(mtcars$wt), ylim = range(mtcars$mpg))
|
|
},
|
|
cacheKeyExpr = { list(input$n) }
|
|
)
|
|
}
|
|
)
|
|
|
|
|
|
|
|
# An example uses a data object shared across sessions. mydata() is part of
|
|
# the cache key, so when its value changes, plots that were previously
|
|
# stored in the cache will no longer be used (unless mydata() changes back
|
|
# to its previous value).
|
|
mydata <- reactiveVal(data.frame(x = rnorm(400), y = rnorm(400)))
|
|
|
|
ui <- fluidPage(
|
|
sidebarLayout(
|
|
sidebarPanel(
|
|
sliderInput("n", "Number of points", 50, 400, 100, step = 50),
|
|
actionButton("newdata", "New data")
|
|
),
|
|
mainPanel(
|
|
plotOutput("plot")
|
|
)
|
|
)
|
|
)
|
|
|
|
server <- function(input, output, session) {
|
|
observeEvent(input$newdata, {
|
|
mydata(data.frame(x = rnorm(400), y = rnorm(400)))
|
|
})
|
|
|
|
output$plot <- renderCachedPlot(
|
|
{
|
|
Sys.sleep(2)
|
|
d <- mydata()
|
|
seqn <- seq_len(input$n)
|
|
plot(d$x[seqn], d$y[seqn], xlim = range(d$x), ylim = range(d$y))
|
|
},
|
|
cacheKeyExpr = { list(input$n, mydata()) },
|
|
)
|
|
}
|
|
|
|
shinyApp(ui, server)
|
|
|
|
|
|
# A basic application with two plots, where each plot in each session has
|
|
# a separate cache.
|
|
shinyApp(
|
|
fluidPage(
|
|
sidebarLayout(
|
|
sidebarPanel(
|
|
sliderInput("n", "Number of points", 4, 32, value = 8, step = 4)
|
|
),
|
|
mainPanel(
|
|
plotOutput("plot1"),
|
|
plotOutput("plot2")
|
|
)
|
|
)
|
|
),
|
|
function(input, output, session) {
|
|
output$plot1 <- renderCachedPlot({
|
|
Sys.sleep(2) # Add an artificial delay
|
|
seqn <- seq_len(input$n)
|
|
plot(mtcars$wt[seqn], mtcars$mpg[seqn],
|
|
xlim = range(mtcars$wt), ylim = range(mtcars$mpg))
|
|
},
|
|
cacheKeyExpr = { list(input$n) },
|
|
cache = cachem::cache_mem()
|
|
)
|
|
output$plot2 <- renderCachedPlot({
|
|
Sys.sleep(2) # Add an artificial delay
|
|
seqn <- seq_len(input$n)
|
|
plot(mtcars$wt[seqn], mtcars$mpg[seqn],
|
|
xlim = range(mtcars$wt), ylim = range(mtcars$mpg))
|
|
},
|
|
cacheKeyExpr = { list(input$n) },
|
|
cache = cachem::cache_mem()
|
|
)
|
|
}
|
|
)
|
|
|
|
}
|
|
|
|
\dontrun{
|
|
# At the top of app.R, this set the application-scoped cache to be a memory
|
|
# cache that is 20 MB in size, and where cached objects expire after one
|
|
# hour.
|
|
shinyOptions(cache = cachem::cache_mem(max_size = 20e6, max_age = 3600))
|
|
|
|
# At the top of app.R, this set the application-scoped cache to be a disk
|
|
# cache that can be shared among multiple concurrent R processes, and is
|
|
# deleted when the system reboots.
|
|
shinyOptions(cache = cachem::cache_disk(file.path(dirname(tempdir()), "myapp-cache")))
|
|
|
|
# At the top of app.R, this set the application-scoped cache to be a disk
|
|
# cache that can be shared among multiple concurrent R processes, and
|
|
# persists on disk across reboots.
|
|
shinyOptions(cache = cachem::cache_disk("./myapp-cache"))
|
|
|
|
# At the top of the server function, this set the session-scoped cache to be
|
|
# a memory cache that is 5 MB in size.
|
|
server <- function(input, output, session) {
|
|
shinyOptions(cache = cachem::cache_mem(max_size = 5e6))
|
|
|
|
output$plot <- renderCachedPlot(
|
|
...,
|
|
cache = "session"
|
|
)
|
|
}
|
|
|
|
}
|
|
}
|
|
\seealso{
|
|
See \code{\link[=renderPlot]{renderPlot()}} for the regular, non-cached version of this
|
|
function. It can be used with \code{\link[=bindCache]{bindCache()}} to get the same effect as
|
|
\code{renderCachedPlot()}. For more about configuring caches, see
|
|
\code{\link[cachem:cache_mem]{cachem::cache_mem()}} and \code{\link[cachem:cache_disk]{cachem::cache_disk()}}.
|
|
}
|