FreyGeospatial
FreyGeospatial

Reputation: 549

How to dynamically add AND remove overlay from plotly histogram in shiny

This R code produces a plotly plot that overlays two histograms together.

fig <- plot_ly(alpha = 0.6)
fig <- fig %>% add_histogram(x = ~rnorm(500))
fig <- fig %>% add_histogram(x = ~rnorm(500) + 1)
fig <- fig %>% layout(barmode = "overlay")

fig

I have a shiny app that contains variable categorical input. Based on user selections, I want to add or remove categories to plot in the histogram. It would be great to be able to add or remove overlays dynamically. Right now it seems like adding overlays dynamically could be possible. Removing them seems more difficult. I'd like to know if my requirement possible?

Upvotes: 0

Views: 680

Answers (1)

ismirsehregal
ismirsehregal

Reputation: 33442

Edit: @FreyGeospatial clarified, that he wants to add/remove traces (I was confused of the wording using overlay).

The easiest way to dynamically add and remove traces is to create a data.frame in long format providing a category column.

In plot_ly you can use split or color to create traces based on this column. To remove traces you can filter categories from a reactive dataset and re-render the plot:

library(shiny)
library(plotly)

DF <- data.frame(values = rnorm(2500), category = rep(LETTERS[1:5], each = 500))

ui <- fluidPage(
  selectizeInput(inputId = "barmode",
                 label = "barmode",
                 choices = c("group", "overlay", "stack"),
                 selected = "overlay"),
  selectizeInput(inputId = "category",
                 label = "category",
                 choices = unique(DF$category), selected = LETTERS[1:3], multiple = TRUE),
  plotlyOutput("myPlot")
)

server <- function(input, output, session) {
  
  filteredDF <- reactive({
    DF[DF$category %in% input$category,]
  })
  
  output$myPlot <- renderPlotly({
    fig <- plot_ly(data = filteredDF(), x = ~ values, split = ~ category, alpha = 0.6, type = "histogram")
    fig <- fig %>% layout(barmode = input$barmode)
    fig
  })
  
}

shinyApp(ui, server)

result

As an alternative to re-rendering the plot you could use plotlyProxy and the addTraces JS function please see my answer here. This is faster than re-rendering but less intutive using plotly's R API.


Please run:

install.packages("listviewer")
schema()

and navigate: object ► traces ► bar ► layoutAttributes ► barmode

To find the barmode description:

default: group

Determines how bars at the same location coordinate are displayed on the graph. With stack, the bars are stacked on top of one another With relative, the bars are stacked on top of one another, with negative values below the axis, positive values above With group, the bars are plotted next to one another centered around the shared location. With overlay, the bars are plotted over one another, you might need to an opacity to see multiple bars.

Upvotes: 1

Related Questions