Michael Silagy
Michael Silagy

Reputation: 11

ggplots not displaying in Shiny

Right now I am trying to build a shinyApp from an alcohol consumption dataset from the world health organization. I've built maps from this data and gotten those outputs to work, but right now I am trying to display the top ten countries in terms of drinks consumed and two of the plots are not displaying (For beer and wine).

You can see what I mean by looking at my shiny app here:

https://mdsil11.shinyapps.io/worldMap/

The weird thing is, my code works when I use simpler plots in place of the ggplotones like hist(rnorm(100)). Another weird thing is that these plots work when I run them in a regular R script. Finally, my last plot(the plot for spirits, or mixed drinks) displays but not for wine or beer.

Here is the code:

library(shiny)
[library(rworldmap)
library(ggplot2)
library(tidyverse)


## defining datasets
wineDrinks = drinks\[ , c(2,5)\]
spiritDrinks = drinks\[ , c(2,4)\]
beerDrinks = drinks\[ , c(2,3)\]

topWine <- wineDrinks %>% arrange(desc(wine_servings))
topBeer <- beerDrinks %>% arrange(desc(beer_servings))
topSpirits <- spiritDrinks %>% arrange(desc(spirit_servings))

top10beer <- topBeer[0:10, ]
top10wine <- topWine[0:10, ]
top10spirits <- topSpirits[0:10, ]

## defining map objects
w <- joinCountryData2Map(drinksISO, joinCode = 'ISO3', nameJoinColumn = 'ISO', verbose = TRUE)
s <- joinCountryData2Map(drinksISO, joinCode = 'ISO3', nameJoinColumn = 'ISO', verbose = TRUE)
b <- joinCountryData2Map(drinksISO, joinCode = 'ISO3', nameJoinColumn = 'ISO', verbose = TRUE)

##### Shiny Application #####

ui <- fluidPage(
  titlePanel('Global Alcohol Consumption'),
  #each input should have a unique input ID
  sidebarPanel(
  radioButtons(inputId = 'Alc', label = 'Alcohol Type',
              choices = list('Beer','Wine','Spirits'))
  )
  , mainPanel(
    plotOutput('map'), plotOutput('TopTen')
    )
)


server <- function(input, output) {
  output$map <- renderPlot({
    if(input$Alc == 'Beer'){
      mapCountryData(mapToPlot = b,nameColumnToPlot = 'beer_servings', mapTitle = 'World Beer Consumption',  missingCountryCol = "grey", oceanCol = "lightblue1")
    }

    if(input$Alc == 'Wine'){
      mapCountryData(mapToPlot = w,nameColumnToPlot = 'wine_servings', mapTitle = 'World Wine Consumption',  missingCountryCol = "grey", oceanCol = "lightblue1")
    }

    if(input$Alc == 'Spirits'){
      mapCountryData(mapToPlot = s, nameColumnToPlot = 'spirit_servings', mapTitle = 'World Spirits Consumption',  missingCountryCol = "grey", oceanCol = "lightblue1")
    }

  })


  output$TopTen <- renderPlot({

     #### PROBLEM LIES HERE #####

    if(input$Alc == 'Beer'){
      ggplot(top10beer,aes(x = reorder(country, -beer_servings), y = beer_servings)) + geom_point(size = 3) + geom_segment(aes(x = country, xend = country, y = 0, yend = beer_servings)) + labs(title="Lollipop Chart", subtitle = 'Top 10 beer drinking countries') + theme(axis.text.x = element_text(angle=65, vjust=0.6)) + xlab('Countries')
    }
    if(input$Alc == 'Wine'){
      ggplot(top10wine, aes(x = reorder(country, -wine_servings), y = wine_servings)) + geom_point(size = 3) + geom_segment(aes(x = country, xend = country, y = 0, yend = wine_servings)) + labs(title="Lollipop Chart", subtitle = 'Top 10 wine drinking countries') + theme(axis.text.x = element_text(angle=65, vjust=0.6)) + xlab('Countries')
    }

   #### BUT THIS WORKS ####

    if(input$Alc == 'Spirits'){
      ggplot(top10spirits,aes(x = reorder(country, -spirit_servings), y = spirit_servings)) + geom_point(size = 3) + geom_segment(aes(x = country, xend = country, y = 0, yend = spirit_servings)) + labs(title="Lollipop Chart", subtitle = 'Top 10 spirit drinking countries') + theme(axis.text.x = element_text(angle=65, vjust=0.6)) + xlab('Countries')
    }
  }
  )

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

Any help/pointers on getting the other two plots to show would be much appreciated!

Upvotes: 1

Views: 61

Answers (1)

MrFlick
MrFlick

Reputation: 206496

Change those separate if statements to an if/else/else. Your renderPlot code block needs to return a ggplot object. If the last line of your block is an if, and that evaluates to FALSE, nothing is returned from the block. The values from previous if statements are basically ignored. Calling ggplot()doesn't actually draw the plot in the same way base graphics functions like hist do. You actually need to print the value returned by ggplot in order to trigger the plot to draw.

Here's one way to re-write your block.

output$TopTen <- renderPlot({

    if(input$Alc == 'Beer'){
      ggplot(top10beer,aes(x = reorder(country, -beer_servings), y = beer_servings)) + geom_point(size = 3) + geom_segment(aes(x = country, xend = country, y = 0, yend = beer_servings)) + labs(title="Lollipop Chart", subtitle = 'Top 10 beer drinking countries') + theme(axis.text.x = element_text(angle=65, vjust=0.6)) + xlab('Countries')
    } else if(input$Alc == 'Wine'){
      ggplot(top10wine, aes(x = reorder(country, -wine_servings), y = wine_servings)) + geom_point(size = 3) + geom_segment(aes(x = country, xend = country, y = 0, yend = wine_servings)) + labs(title="Lollipop Chart", subtitle = 'Top 10 wine drinking countries') + theme(axis.text.x = element_text(angle=65, vjust=0.6)) + xlab('Countries')
    } else if (input$Alc == 'Spirits'){
      ggplot(top10spirits,aes(x = reorder(country, -spirit_servings), y = spirit_servings)) + geom_point(size = 3) + geom_segment(aes(x = country, xend = country, y = 0, yend = spirit_servings)) + labs(title="Lollipop Chart", subtitle = 'Top 10 spirit drinking countries') + theme(axis.text.x = element_text(angle=65, vjust=0.6)) + xlab('Countries')
    } else {
        stop("unknown plot type")
    }
})

Upvotes: 2

Related Questions