nimliug
nimliug

Reputation: 413

Plotly R: Filtering Bars by Category Without Showing Extra Categories with buttons

here is my code. I am trying to create an interactive bar chart with Plotly in R, where buttons allow the user to select either Company 1 or Company 2.
However, when I filter the data using Plotly, some categories (EPISD) that do not belong to the selected company remain displayed on the x-axis.

I want each company to display only the corresponding EPISD values without showing empty or unrelated categories.

library(plotly)
library(data.table)

# Données
dt <- data.table(
  EPISD = c("A", "A", "B", "B", "C", "D", "D"),
  ENTRP = c(
    "company 1",
    "company 2",
    "company 1",
    "company 2",
    "company 2",
    "company 1",
    "company 2"
  ),
  prct_na = c(100, 0, 100, 5.3, 100, 94, 100)
)

plot_ly() %>%
  add_trace(
    data = dt[ENTRP == "company 1"],
    x = ~ EPISD,
    y = ~ prct_na,
    name = 'company 1',
    type = 'bar',
    visible = T
  ) %>%
  add_trace(
    data = dt[ENTRP == "company 2"],
    x = ~ EPISD,
    y = ~ prct_na,
    name = 'company 2',
    type = 'bar',
    visible = F
  ) %>%
  layout(updatemenus = list(list(
    type = "buttons",
    direction = "down",
    buttons = list(
      list(
        method = "restyle",
        args = list("visible", list(T, F)),
        label = "company 1"
      ),
      list(
        method = "restyle",
        args = list("visible", list(F, T)),
        label = "company 2"
      )
    )
  )))

Upvotes: 2

Views: 63

Answers (1)

Tim G
Tim G

Reputation: 4147

So there are a couple of reason why unused x-breaks stay

  1. Switchting the visibility of two dataplots with list(T, F) does not cause plotly to update the categoryarray of the x.axis
  2. So we have to explicitly tell plotly the new x-axis values pertaining to each company AND
  3. update the xaxis list parameter categoryorder to redraw the x-axis

You can also change layout attributes using method = update following this vignette. This allows to update the title for example.

Code

library(plotly)
library(data.table)

dt <- data.table( EPISD = c("A", "A", "B", "B", "C", "D", "D", "A", "F", "G", "F"), 
                  ENTRP = c( "company 1", "company 2", "company 1", "company 2", "company 2", "company 1", "company 2", "company 3", "company 3", "company 4", "company 4"), 
                  prct_na = c(100, 2, 100, 5.3, 100, 94, 100, 25, 14, 50, 10) )

companies <- unique(dt$ENTRP)

buttons_list <- lapply(seq_along(companies), function(i) { # build buttons list using lapply
  company <- companies[i]
  company_data <- dt[ENTRP == company]
  
  list(
    label = company,
    method = "update",
    args = list(
      list(
        x = list(company_data$EPISD), # set x values as before
        y = list(company_data$prct_na) # set y values as before
      ),
      list(
        title = paste(company, "Data"),
        xaxis = list(
          categoryorder = "category ascending"
        )
      )
    )
  )
})

plot_ly(x = dt[ENTRP == companies[1]]$EPISD, 
        y = dt[ENTRP == companies[1]]$prct_na, 
        type = 'bar',
        name = companies[1]) %>%
  layout(
    title = paste(companies[1], "Data"),
    xaxis = list(
      categoryorder = "category ascending"
    ),
    updatemenus = list(
      list(
        type = "buttons",
        direction = "down",
        buttons = buttons_list
      )
    )
  )

Upvotes: 2

Related Questions