Shiny plots draw in Rstudio instead of browser window

I am working on a game for a time series class. In order to learn how to find frequencies in data we match two kinds of plots, a time series plot and a spectral density plot. My app creates a game where it generates four different time series and the associated spectral density plots, then presents them in a random order. The user thinks about the correct match then clicks the show answer button to re-arrange them in the correct order.

When I run the app and generate the game, all the plots draw in R studio and the browser windows just remains empty, besides my two action buttons. From my google search, the issue might be with the grid objects from gridExtra, which might be choosing Rstudio as the default plot device. Some solutions have pointed out improper use of reactive objects as a cause.

How can I resolve the issue? Can I specify the browser as the plot area? Have I used reactive elements improperly?

Thank you!

library(shiny)
library(tswge)
library(ggplot2)
library(ggplotify)
library(grid)
library(gridExtra)

# Define UI for application that draws a histogram
ui <- fluidPage(

    # Application title
    titlePanel("Spectral Density Guessing Game"),

    # Sidebar with a slider input for number of bins 
    sidebarLayout(
        sidebarPanel(
            actionButton("goButton1", "Generate Game"),
            actionButton("goButton2", "Show Answers")
        ),

        # Show a plot of the generated distribution
        mainPanel(
           plotOutput("gamePlot")
        )
    )
)

# function to create data in the right format
createDensityData <- function(dens) {
    data <- data.frame(dens$freq,dens$pzgram)
    names(data) <- c("Frequency","pzgram")
    data
}

createGame <- function() {
    
    ## create four unique time series
    n=50
    whiteNoise <- gen.sigplusnoise.wge(n=n, vara = runif(1,1,10), plot = FALSE)
    oscilation <- gen.sigplusnoise.wge(n=n, coef=c(10,10),freq = c(0.5,0.5), plot = FALSE)
    freqTrend <- gen.sigplusnoise.wge(n=n, b1 = runif(1,1,3), coef=c(10,10), freq = runif(2,0,.5), plot = FALSE)
    freqNoTrend <- gen.sigplusnoise.wge(n=n, freq = runif(2,0,.5), coef=c(10,10), plot = FALSE)
    Time<- c(1:n)
    myReals <- data.frame(whiteNoise,oscilation,freqTrend,freqNoTrend,Time)
    
    
    # create denisty data frames
    WNDensity <- createDensityData(parzen.wge(ts(myReals[1])))
    OSCDensity <- createDensityData(parzen.wge(ts(myReals[2])))
    fTDensity <- createDensityData(parzen.wge(ts(myReals[3])))
    fNtDensity <- createDensityData(parzen.wge(ts(myReals[4])))
    
    # create plot objects for the time series
    WNRealPlot <- ggplot(myReals,aes(Time,whiteNoise)) +geom_line() + xlab("Time") + ylab("")
    OSCRealPlot<- ggplot(myReals,aes(Time,oscilation)) +geom_line() + xlab("Time") + ylab("")
    fTRealPlot<- ggplot(myReals,aes(Time,freqTrend)) +geom_line() + xlab("Time") + ylab("")
    fNtRealPlot<- ggplot(myReals,aes(Time,freqNoTrend)) +geom_line() + xlab("Time") + ylab("")
    
    # create plot objects for the densities
    WNDensPlot <- ggplot(WNDensity,aes(Frequency,pzgram)) +geom_line() + xlab("Frequency") + ylab("")
    OSCDensPlot<- ggplot(OSCDensity,aes(Frequency,pzgram)) +geom_line() + xlab("Frequency") + ylab("")
    fTDensPlot<- ggplot(fTDensity,aes(Frequency,pzgram)) +geom_line() + xlab("Frequency") + ylab("")
    fNtDensPlot<- ggplot(fNtDensity,aes(Frequency,pzgram)) +geom_line() + xlab("Frequency") + ylab("")
    
    # grouping plot objects
    realizations <- list(WNRealPlot,OSCRealPlot,fTRealPlot,fNtRealPlot)
    densities <- list(WNDensPlot,OSCDensPlot,fTDensPlot,fNtDensPlot)
    
    # creating randomizers
    scrambler <- sample(1:4,4)
    scrambler2 <- sample(1:4,4)
    
    # grid plots for time series and densities in a random order
    guessPlot <- arrangeGrob(realizations[[scrambler[1]]] + ggtitle("Realization A"), 
                 realizations[[scrambler[2]]] + ggtitle("Realization B"),
                 realizations[[scrambler[3]]] + ggtitle("Realization C"),
                 realizations[[scrambler[4]]] + ggtitle("Realization D"),
                 densities[[scrambler2[1]]] + ggtitle("Density 1"),
                 densities[[scrambler2[2]]] + ggtitle("Density 2"),
                 densities[[scrambler2[3]]] + ggtitle("Density 3"),
                 densities[[scrambler2[4]]] + ggtitle("Density 4"), 
                 ncol=2)
    # grid plots for time series and densities in the correct order
    answerPlot <- arrangeGrob(realizations[[scrambler[1]]] + ggtitle("Realization A"), 
                 realizations[[scrambler[2]]] + ggtitle("Realization B"),
                 realizations[[scrambler[3]]] + ggtitle("Realization C"),
                 realizations[[scrambler[4]]] + ggtitle("Realization D"),
                 densities[[scrambler[1]]] + ggtitle("Density A"),
                 densities[[scrambler[2]]] + ggtitle("Density B"),
                 densities[[scrambler[3]]] + ggtitle("Density C"),
                 densities[[scrambler[4]]] + ggtitle("Density D"), 
                 ncol=2)
}

server <- function(input, output) {
    
    v <- reactiveValues(game = NULL, plot = NULL)
    
    observeEvent(input$goButton1, {
        v$game <- createGame()
        v$plot <- v$game$guessPlot
    })
    
    observeEvent(input$goButton2, {
        v$plot <- v$game$answerPlot
    })

    output$gamePlot <- renderPlot({
        if (is.null(v$plot)) return()
        grid.draw(v$plot)
    })
    
}

# Run the application 
shinyApp(ui = ui, server = server)

Can you start by making a simple reprex? I suspect you should be able to illustrate the problem with a single plot.

(You might also try patchwork instead of gridExtra since that works at the ggplot2 level, rather than the grid level)

@hadley thank you for the reprex reference, I will try to create a simpler version of the issue. I will also try patchwork.

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.