I have made three reactive layers in my graph. In the reproducible example below, the graph starts with function1 drawn. If I check function2, shiny recalculates and redraws function1 and function2. Then if I tick function3, all 3 functions are recalculated and redrawn.
Say the functions I want to run are very long inferences that take several minutes each.
How can I make it so that when I check (or uncheck) one function, shiny does not recalculate and redraw all checked functions?
In the code below, I have included print statements which show that each reactive is run each time renderPlot is called (which is when input$fun changes).
library(shiny)
library(ggplot2)
x <- seq(0, 10, by=0.1)
runApp(shinyApp(
ui = shinyUI(fluidPage(
titlePanel("Test Shiny"),
sidebarLayout(
sidebarPanel(
checkboxGroupInput("fun", label = "Function",
choices = list("function1: x^2" = 1,
"function2: x^2 + x" = 2,
"function3: x^2 - x" = 3),
selected = c(1))
),
mainPanel(
plotOutput("plot")
)
)
)),
server = shinyServer(function(input, output) {
fn1 <- reactive({
print("we are in fn1 <- reactive({})")
if (1 %in% input$fun ) {
geom_line(mapping = aes(x, y=x^2), color="blue") }
})
fn2 <- reactive({
print("we are in fn2 <- reactive({})")
if (2 %in% input$fun) {
geom_line(mapping = aes(x, y=x^2 + x), color="red") }
})
fn3 <- reactive({
print("we are in fn3 <- reactive({})")
if (3 %in% input$fun) {
geom_line(mapping = aes(x, y=x^2 - x), color="green") }
})
output$plot <- renderPlot({
cat("\n we are in output$plot <- renderPlot({}) \n")
ggplot() + fn1() + fn2() + fn3()
})
})
))
I can achieve this efficiency using single checkboxes (checkboxInput) but I would prefer not to use single checkboxes. Single checkboxes don’t look as good, unless there is a way to make them look more like checkbox Group Inputs?
I have been trying to work this out and searching SO for some time. I would be very grateful for any help with this!!!
EDIT
Here is some code in response to @Jimbou ’s shiny code using base R plot()
and lines()
. Please see my comment below the shiny code @Jimbou provided.
output$plot <- renderPlot({
cat("\n we are in output$plot <- renderPlot({}) \n")
plot(NULL, xlim = c(0,10), ylim = c(0,100))
if(1 %in% input$fun) {
print("we are in if(1 %in% input$fun){} ")
lines(x=x, y=x^2, col=2)
}
if(2 %in% input$fun) {
print("we are in if(2 %in% input$fun){} ")
lines(x=x, y=x^2 + x, col=3)
}
if(3 %in% input$fun) {
print("we are in if(3 %in% input$fun){} ")
lines(x=x, y=x^2 - x, col=4)
}
})