I am working on a Shiny App that takes a simple input (I1) and creates a large amount (N1 > 100) of plots (using ggplot2) from that. I want to arrange the plots in a grid. The number of rows of this grid is fixed (N2), but the number of columns (N3) will depend on the input (I1) provided by the user. I have managed to get the desired result but the computation takes much too long and I am looking for a faster way to do this.
So far I have tried the following R packages to combine plots into a single grid plot: cowplot
, gridExtra
, ggplot2
(facet_wrap
, facet_grid
), plotly
. But they have all performed too slowly to be of use.
My next idea is to somehow merge all of these plots outside of R, but I am unsure how to go about this. Does anyone have any ideas how to process a large amount of plots into a structured single plot?
Here is an example version of the app and my current implementation with cowplot:
library(ggplot2)
library(gridExtra)
library(shiny)
library(shinyBS)
library(shinyWidgets)
library(cowplot)
ui = fluidPage(
sidebarLayout(
sidebarPanel(
style = "position:fixed;width:inherit;",
textInput(inputId = "I1", label = "Input1", value = 1),
actionBttn(inputId = "StartPlot", label = "Plot", style = "jelly",
color = "primary", size = "s"),
width=2
),
# Show a plot of the generated distribution
mainPanel(
imageOutput("mainPlot", click = clickOpts(id="plot_click")),
)
)
)
server = function(input, output, session) {
plotWidth = 1350
plotHeight = 6000
plotQuality = 1
randomPlots = function(n = 100) {
l = list()
for(i in 1:n) {
data = data.frame(runif(n = 1000), runif(n = 1000))
colnames(data) = c("x", "y")
l[[i]] = ggplot(data = data, aes(x = x, y = y)) + geom_point()
}
l
}
# Create Plots and store as reactive
plotsReactive = reactive({
req(input$StartPlot)
p <- randomPlots()
p
})
# Arrange plots in a grid
plotGridReactive = reactive({
req(plotsReactive())
plotList = plotsReactive()
print(do.call(plot_grid, plotList))
})
# Render Grid Plot
output$mainPlot <- renderImage({
# A temp file to save the output.
# This file will be removed later by renderImage
outfile <- tempfile(fileext = '.png')
# Generate the PNG
png(outfile,
# width = plotWidth * plotQuality,
# height = plotHeight * plotQuality,
width = plotWidth,
height = plotHeight,
res = 72*plotQuality
)
plotGridReactive()
dev.off()
# Return a list containing the filename
list(src = outfile,
contentType = 'image/png',
width = plotWidth,
height = plotHeight,
res = 72*plotQuality,
alt = "This is alternate text")
}, deleteFile = TRUE)
}
shinyApp(ui, server)