Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shiny not displaying my ggplot as I'd expect

Tags:

r

ggplot2

shiny

What's keeping my little Shiny app from displaying my ggplot? When I replace the code in renderPlot() with an example using the base plot function it comes together. I'm using RStudio, R v3.0.1 on Windows Vista, outputting to a Chrome browser.

ui.r

library(ggplot2)

cities <- c("Anchorage","Fairbanks","Juenau","Wasilla","Homer")
years <- 2003:2013
Table <- "Capital Assets"
Account <- c("Land", "Art", "Buildings", "Equipment")
dat <- data.frame(City = sort(rep(cities, length(years))), Year = rep(years,length(cities)), Table)
sampleDat <- rbind(data.frame(dat,Acount = Account[1]), data.frame(dat, Acount = Account[2]), data.frame(dat, Acount = Account[3]), data.frame(dat, Acount = Account[4]))
finalDat <- data.frame(sampleDat, Value = runif(length(sampleDat[,1]), 1000,10000) )

shinyUI(pageWithSidebar(

  headerPanel("CAFR Explorer"),

  selectInput("city","City", as.list(levels(finalDat$City)), selected = NULL, multiple = FALSE),

  mainPanel(
    h3(textOutput("caption")),

    plotOutput("CAFRplot")
)))   

server.r

library(shiny)
library(ggplot2)

cities <- c("Anchorage","Fairbanks","Juenau","Wasilla","Homer")
years <- 2003:2013
Table <- "Capital Assets"
Account <- c("Land", "Art", "Buildings", "Equipment")
dat <- data.frame(City = sort(rep(cities, length(years))), Year = rep(years,length(cities)), Table)
sampleDat <- rbind(data.frame(dat,Acount = Account[1]), data.frame(dat, Acount = Account[2]), data.frame(dat, Acount = Account[3]), data.frame(dat, Acount = Account[4]))
finalDat <- data.frame(sampleDat, Value = runif(length(sampleDat[,1]), 1000,10000) )

shinyServer(function(input, output) {

  formulaText <- reactive({
    paste(input$city)
  })

  output$caption <- renderText({
    formulaText()
  })

  output$CAFRplot <- renderPlot({

    ## this one isn't working.
    ggplot(finalDat, aes(x = finalDat[which(finalDat$City == input$city),2], 
                         y = finalDat[which(finalDat$City == input$city),5])) +
    geom_point()

    ## this one is working
    #plot(finalDat[which(finalDat$City == input$city),2], y = finalDat[which(finalDat$City == input$city),5])


  })
})
like image 706
cylondude Avatar asked Aug 04 '13 01:08

cylondude


3 Answers

There are two issues here.

First, you shouldn't subset in aes -- it expects column names. Instead, subset the data.frame that you provide to ggplot (thanks to @Roland from R chat)

Second, you must explicitly print your ggplot object in your shiny app.

Try this:

p <- ggplot(finalDat[finalDat$City == input$city,], aes(x = Year, y = Value))
p <- p + geom_point()
print(p)
like image 158
GSee Avatar answered Sep 21 '22 15:09

GSee


Your code needed a couple of changes to get ggplot to render. As the comments above state, print(ggplot) was needed. But also, aes inside ggplot can't deal with subsetting.

So you subset your city of interest in a separate reactive, and call that from ggplot.

city.df <- reactive({
    subset(finalDat, City == input$city)
  })  

  output$CAFRplot <- renderPlot({
    city <- city.df()

    print(ggplot(city, aes(x = Year, y=Value)) + geom_point())

The full server.R (this works)

library(shiny)
library(ggplot2)

cities <- c("Anchorage","Fairbanks","Juenau","Wasilla","Homer")
years <- 2003:2013
Table <- "Capital Assets"
Account <- c("Land", "Art", "Buildings", "Equipment")
dat <- data.frame(City = sort(rep(cities, length(years))), Year = rep(years,length(cities)), Table)
sampleDat <- rbind(data.frame(dat,Acount = Account[1]), data.frame(dat, Acount = Account[2]), data.frame(dat, Acount = Account[3]), data.frame(dat, Acount = Account[4]))
finalDat <- data.frame(sampleDat, Value = runif(length(sampleDat[,1]), 1000,10000) )

shinyServer(function(input, output) {

  formulaText <- reactive({
    paste(input$city)
  })

  output$caption <- renderText({
    formulaText()
  })

  city.df <- reactive({
    subset(finalDat, City == input$city)
  })  

  output$CAFRplot <- renderPlot({
    city <- city.df()
    ## this one isn't working.
#    print(ggplot(finalDat, aes(x = finalDat[which(finalDat$City == input$city),2], 
#                         y = finalDat[which(finalDat$City == input$city),5])) +  geom_point())

    print(ggplot(city, aes(x = Year, y=Value)) + geom_point())

    ## this one is working
    #plot(finalDat[which(finalDat$City == input$city),2], y = finalDat[which(finalDat$City == input$city),5])


  })
})
like image 3
Ram Narasimhan Avatar answered Sep 21 '22 15:09

Ram Narasimhan


In ggplot2 you can subset the overall data being passed to all layers (@GSee's answer) or, for indivdual layers you can use the subset argument to subset just for that layer. This may be useful if you are constructing more complex plots.

Using the plyr function . is useful here for constructing the arguments

# required in server.R (along with the other calls to library)
library(plyr)

 p <- ggplot(finalDat, aes(y =Year, x = Value)) + 
        geom_point(subset = .(City ==input$city))
 print(p)
like image 2
mnel Avatar answered Sep 18 '22 15:09

mnel