Multiple lines and filter

I am trying to plot 3 types of data (A, B, C), and to filter them with respect to two time points (1, 2).

Here is a minimum working example:

set.seed(1234)
data.frame(a = rep(c(1, 2), each = 6),
             b = rep(c("A", "B", "C"), 4),
             x = runif(12),
             y = runif(12)) %>%
  plot_ly(x = ~x,
      y = ~y,
      type = 'scatter', 
      mode = 'markers',
      color = ~b,
      transforms = list(list(
           type = 'filter',
           target = ~a,
           operation = '=',
           value = 1))) %>%
  layout(updatemenus = list(
       list(
         type = 'dropdown',
         active = 0,
         buttons = apply(as.data.frame(c(1, 2)), 1,
                         function(x) list(method = 'restyle',
                                          args = list('transforms[0].value', x),
                                          label = x)))
       )
     )

Strangely enough, the “C” dots does not appear, but are merged with the “A” dots.

Adding

filter(a == 1) %>%

Solves the problem. But, I am ultimately willing to add an updatemenus.

It seems a bug to me. What do you think?

Instead of using the legend as a filter, a different workaround would be to create a second dropdown menu for column b. The only disadvantage here is that you will lose the legend.

Here is my approach.

I added a column for the colors of A, B and C in order to distinguish between them. This new column will be needed inside the marker.

set.seed(1234)

df <- data.frame(a = rep(c(1, 2), each = 6),
             b = rep(c("A", "B", "C"), 4),
             x = runif(12),
             y = runif(12)) %>%
  mutate(colors = case_when(b == "A" ~ "#009933",
                            b == "B" ~ "#FF6666",
                            b == "C" ~ "#710933",
                            TRUE ~ "#999999"))


fig <- plot_ly(data = df, 
               x=~x, 
               y=~y,
               type = "scatter", 
               mode = "markers",
               marker = list(color = ~colors, 
                             size = 20),
               text = ~paste(a, b),

            transforms = list(
              list(
                type = "filter",
                target = ~a,
                operation = '{}',
                value = unique(df$a)
                ),
              list(
                type = "filter",
                target = ~b,
                operation = '{}',
                value = unique(df$b)
                ) 
              ) 
            ) %>%
  
  layout( 
    updatemenus = list(
      list(
        type = 'dropdown',
        active = 0,
        buttons = list(

          list(method = "restyle",
               args = list("transforms[0].value", list(unique(df$a))),
               label = "all 'a'"),

          list(method = "restyle",
               args = list("transforms[0].value", unique(df$a)[1]),
               label = unique(df$a)[1]),

          list(method = "restyle",
               args = list("transforms[0].value", unique(df$a)[2]),
               label = unique(df$a)[2])
        )
      ),
      
      list(
        type = 'dropdown',
        active = 0,
        y = 0.75,
        buttons = list(

          list(method = "restyle",
               args = list("transforms[1].value", list(unique(df$b))),
               label = "all 'b'"),

          list(method = "restyle",
               args = list("transforms[1].value", unique(df$b)[1]),
               label = unique(df$b)[1]),

          list(method = "restyle",
               args = list("transforms[1].value", unique(df$b)[2]),
               label = unique(df$b)[2]),

          list(method = "restyle",
               args = list("transforms[1].value", unique(df$b)[3]),
               label = unique(df$b)[3])
        )
      )
    )
  )

fig

As I wanted to be able to filter all entries as well I came across the operation with ‘{}’. This gave me the idea:

https://stackoverflow.com/questions/62630417/r-plotly-filter-button-to-display-all-data