Having trouble with multiple selection of bars in a ggplot2 bar graph in Shiny

425 views
Skip to first unread message

rdabbler

unread,
Aug 18, 2017, 5:43:35 PM8/18/17
to Shiny - Web Framework for R
Hello,

I am trying to get data based on doing multiple selections of bars in a ggplot2 bar graph within shiny. Also the unselected bars have increased transparency thus highlighting the selected bars. I have listed the code below. It seems like it is working but the selection of bars and the filtered dataset seems to disappear immediately after rendering. I would appreciate any help on this.

Thanks,
Shankar

#
#   Goal: In a bar graph, I want to click multiple bars and get the data for that and also highlight just the clicked bars by increasing transparency
#   for non-clicked bars
#


library(shiny)
library(ggplot2)

# Create dataframe
df = data.frame(x = c("A", "A", "B", "B", "C", "C"), y = c(1/2, 1/2, 1/3, 2/3, 1/4, 3/4), z = c("X", "Y", "X", "Y", "X", "Y"))

# ui
ui = fluidPage(
    headerPanel("Test Multiple Selection Bar Plot"),
    plotOutput("plot1", click = "plot1_click"),
    br(),
    br(),
    br(),
    verbatimTextOutput("testdf")
)

# server
server = function(input, output) {
    
    # rv is the reactive value to store cumulatively the clicked bars in bar graph
    rv = reactiveValues(clickgrp = NULL)
    
    # get the dataframe based on selected bars in bargraph
    getdf = eventReactive(input$plot1_click$x, {
        
        rv$clickgrp = c(rv$clickgrp, input$plot1_click$x)
        keeprows <- as.numeric(df$x) %in% round(rv$clickgrp) 
        df2 = df[keeprows, ]
        df2c = df[!keeprows, ]
        
        list(df2 = df2, df2c = df2c)
    })
    
    # bar plot
    output$plot1 = renderPlot({
        
        if(!is.null(input$plot1_click$x)) {
            df2 = getdf()$df2
            df2c = getdf()$df2c
        } else {
            df2 = df
            df2c = NULL
        }
        
        p = ggplot() + geom_bar(data = df2, aes(x = x, y = y, fill = z), stat = "identity") 
        if(!is.null(df2c)) {
            p = p + geom_bar(data = df2c, aes(x = x, y = y, fill = z), alpha = 0.3, stat = "identity") 
        }
        p = p + scale_fill_discrete(drop = FALSE) + theme_bw()
        p
    })
    
    output$testdf = renderPrint({
        if(!is.null(input$plot1_click$x)) {
            getdf()$df2
        } else {
            df
        }
    })
}

shinyApp(ui, server)

The session info with package versions I used is below

R version 3.4.1 (2017-06-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252 LC_NUMERIC=C                           LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggplot2_2.2.1 shiny_1.0.3  




rdabbler

unread,
Aug 18, 2017, 10:42:59 PM8/18/17
to Shiny - Web Framework for R

Never mind, I found out my mistake. The ShinyDevCon video by Winston Change helped where he talks about adding points to a graph. The link to the video is:
He specifically talks about the adding of points to a graph around 13 min. I modified the above code accordingly and have put the version of code below which works fine.

#
#   Goal: In a bar graph, I want to click multiple bars and get the data for that and also highlight just the clicked bars by increasing transparency
#   for non-clicked bars
#


library(shiny)
library(ggplot2)

# Create dataframe
df = data.frame(x = c("A", "A", "B", "B", "C", "C"), y = c(1/2, 1/2, 1/3, 2/3, 1/4, 3/4), z = c("X", "Y", "X", "Y", "X", "Y"))

# ui
ui = fluidPage(
  headerPanel("Test Multiple Selection Bar Plot"),
  plotOutput("plot1", click = "plot1_click"),
  br(),
  br(),
  actionButton("clearfilter", "Clear Filters"),
  br(),
  br(),
  br(),
  verbatimTextOutput("testdf")
)

# server
server = function(input, output) {
  
  # rv is the reactive value to store cumulatively the clicked bars in bar graph
  rv = reactiveValues(clickgrp = NULL, dfr = df, dfrc = NULL)
  
  # get the dataframe based on selected bars in bargraph
  observeEvent(input$plot1_click$x, {
    
    rv$clickgrp = c(rv$clickgrp, input$plot1_click$x)
    keeprows <- as.numeric(df$x) %in% round(rv$clickgrp) 
    rv$dfr = df[keeprows, ]
    rv$dfrc = df[!keeprows, ]

  })
  
  observeEvent(input$clearfilter, {
    
    rv$clickgrp = NULL
    rv$dfr = df
    rv$dfrc = NULL
  })
  
  # bar plot
  output$plot1 = renderPlot({
    
      df2 = rv$dfr
      df2c = rv$dfrc

    p = ggplot() + geom_bar(data = df2, aes(x = x, y = y, fill = z), stat = "identity") 
    if(!is.null(df2c)) {
      p = p + geom_bar(data = df2c, aes(x = x, y = y, fill = z), alpha = 0.3, stat = "identity") 
    }
    p = p + scale_fill_discrete(drop = FALSE) + theme_bw()
    p
  })
  
  output$testdf = renderPrint({
    rv$dfr
  })
}

shinyApp(ui, server)




Reply all
Reply to author
Forward
0 new messages