What is the simplest way to make an interactive bar plot with multiple drop down filters with Shiny and ggplot combo?

I know it sounds a bit basic, but I would like to make an interactive barplot which can handle multiple x and y axis whether the user would like to use it.

I started it like this way however I know there are many things which are need to be added.

library(dplyr)
library(shiny)
library(ggplot2)

# Sample workable data

sample <- data.frame("Country" = c("Australia", "Bangladesh",
                                     "Argentina", "Slovakia", "Greece", "Sweden"),
                       "Attribute1" = 57:62,
                       "Attribute2" = 13:18,
                       "Attribute3" = 5:10)

# Since I cannot enter the choices one by one..

Atts <- sample %>%
  select(Attribute1:Attribute3) %>%
  names() 

Ctrs <- unique(sample$Country)


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

  # Application title
  titlePanel("Sample Drop Down"),

  # Sidebar with dropdown

  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "selects", choices = Ctrs,
                  label = "Select Region", multiple = TRUE),
      selectInput(inputId = "selects2", choices = Atts, label = "select attribute",
                  multiple = TRUE)
    ),

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



# Define server logic required to draw a histogram
server <- function(input, output) {

  output$Plot <- renderPlot({
    ggplot(data = sample, aes(x = input$selects, y= input$selects2)) + 
      geom_bar(stat = "identity", color = "blue", fill = "Country")
  })
}

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

So how do I link the UI and Server part together? And basically how do reactive plots work?

Hi @gergeli. I can't get what you wanna do. The following code is by my guess.

library(dplyr)
library(shiny)
library(ggplot2)

# Sample workable data

sample <- data.frame("Country" = c("Australia", "Bangladesh",
                                   "Argentina", "Slovakia", "Greece", "Sweden"),
                     "Attribute1" = 57:62,
                     "Attribute2" = 13:18,
                     "Attribute3" = 5:10)

# Since I cannot enter the choices one by one..

Atts <- sample %>%
  select(Attribute1:Attribute3) %>%
  names() 

Ctrs <- unique(sample$Country)


# Define UI for application that draws a histogram
ui <- fluidPage(
  
  # Application title
  titlePanel("Sample Drop Down"),
  
  # Sidebar with dropdown
  
  sidebarLayout(
    sidebarPanel(
      selectInput(inputId = "selects", choices = Ctrs,
                  label = "Select Region", multiple = TRUE),
      selectInput(inputId = "selects2", choices = Atts, label = "select attribute",
                  multiple = TRUE)
    ),
    
    # Show a plot of the generated distribution
    mainPanel(
      plotOutput("Plot")
    )
  )
)



# Define server logic required to draw a histogram
server <- function(input, output) {
  
  output$Plot <- renderPlot({
    data = sample %>%
      filter(Country %in% input$selects) %>%
      select(one_of(c("Country", input$selects2))) %>%
      gather(Attribute, value, -Country)
    
    ggplot(data = data, aes(x = Country, y= value)) + 
      geom_bar(aes(group = Attribute, fill = Country), stat = "identity", color = "blue")
  })
}

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

Hi!

It looks good. And what is the trick to make the attribute columns stacked for each country?

like the bars in this picture:

image

1 Like

Okay. I just figured that out.


  output$Plot <- renderPlot({
    data = sample %>%
      filter(Country %in% input$selects) %>%
      select(one_of(c("Country", input$selects2))) %>%
      gather(Attribute, value, -Country)
    
    ggplot(data = data, aes(x = Country, y= value)) + 
      geom_bar(aes(group = Attribute, fill = Attribute), stat = "identity", position = "dodge", color = "black")

Many thanks!

Perhaps can you point out why my code didn't linked with the data? What is the logic behind your code here...?

Thank you in advance!

@gergeli. Your code problem just the data table pass to ggplot is not right. The concept of ggplot is column based, so you cannot use the two selectInput directly as the arguments of aes because they are not the column name. You have to use the two selectInput to tidy your data and made the useful data in column. For example, I select Australia, Bangladesh and Argentina in input$selects and Attribute1 and Attribute2 in input$selects2. The data pass to ggplot will like the following.

library(tidyverse)

sample <- data.frame("Country" = c("Australia", "Bangladesh",
                                   "Argentina", "Slovakia", "Greece", "Sweden"),
                     "Attribute1" = 57:62,
                     "Attribute2" = 13:18,
                     "Attribute3" = 5:10)

sample %>%
  filter(Country %in% c("Australia", "Bangladesh", "Argentina")) %>%
  select(one_of(c("Country", c("Attribute1", "Attribute2")))) %>%
  gather(Attribute, value, -Country)
#>      Country  Attribute value
#> 1  Australia Attribute1    57
#> 2 Bangladesh Attribute1    58
#> 3  Argentina Attribute1    59
#> 4  Australia Attribute2    13
#> 5 Bangladesh Attribute2    14
#> 6  Argentina Attribute2    15

Created on 2020-01-09 by the reprex package (v0.3.0)

1 Like

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