Search code examples
rplotlyr-plotly

Plotly filter not working with transforms


I've made a filtered plotly stacked bar chart however it is showing empty spaces for bars that don't exist under the specified filter.

Here is my code:

event <- c("eve1","eve2","eve3","eve1","eve3","eve4","eve3","eve1","eve1","eve2","eve3","eve4","eve2","eve1")
year <-c("2017","2017","2017","2018","2018","2019","2019","2019","2020","2020","Total","Total","Total","Total")
cat1 <- c(20,14,25,64,0,5,34,2,14,6,78,0,0,23)
cat2 <- c(0,4,0,4,3,9,0,2,4,12,8,42,31,2)

eve <- data.frame(event,year,cat1,cat2)

fig <- plot_ly(eve, x = ~event, y = ~cat1, type = 'bar', name = 'cat1',
               transforms = list(list(type = 'filter',target = ~year, operation = '=',value = eve$year))) %>% 
  add_trace(y = ~cat2, name = 'cat2')%>% 
  layout(yaxis = list(title = 'count'), barmode = 'stack', 
         updatemenus = list(list(type = 'dropdown',active = 0,buttons = 
                                   list(list(method = "restyle",
                                             args = list("transforms[0].value", unique(eve$year)[1]),
                                             label = unique(eve$year)[1]),
                                        list(method = "restyle",
                                             args = list("transforms[0].value", unique(eve$year)[2]),
                                             label = unique(eve$year)[2]),
                                        list(method = "restyle",
                                             args = list("transforms[0].value", unique(eve$year)[3]),
                                             label = unique(eve$year)[3]),
                                        list(method = "restyle",
                                             args = list("transforms[0].value", unique(eve$year)[4]),
                                             label = unique(eve$year)[4]),
                                        list(method = "restyle",
                                             args = list("transforms[0].value", unique(eve$year)[5]),
                                             label = unique(eve$year)[5])
                                        ))))

fig

Why is "eve2" appearing for 2019 when it doesn't appear in the data?


Solution

  • Found the solution a couple of months later, posting it in case anyone else comes across a similar issue.

    Under layout you need to specify categoryorder and categoryarray. This stops Plotly from auto-sorting the dataframe which can interfere with the transforms element of the filter.

    Here is the corrected code:

    event <- c("eve1","eve2","eve3","eve1","eve3","eve4","eve3","eve1","eve1","eve2","eve3","eve4","eve2","eve1")
    year <-c("2017","2017","2017","2018","2018","2019","2019","2019","2020","2020","Total","Total","Total","Total")
    cat1 <- c(20,14,25,64,0,5,34,2,14,6,78,0,0,23)
    cat2 <- c(0,4,0,4,3,9,0,2,4,12,8,42,31,2)
    
    eve <- data.frame(event,year,cat1,cat2)
    
    fig <- plot_ly(eve, x = ~event, y = ~cat1, type = 'bar', name = 'cat1',
                   transforms = list(list(type = 'filter',target = ~year, operation = '=',value = eve$year))) %>% 
      add_trace(y = ~cat2, name = 'cat2')%>% 
      layout(yaxis = list(title = 'count'),xaxis=list(categoryorder = "array",
                  categoryarray = eve$year), barmode = 'stack', 
             updatemenus = list(list(type = 'dropdown',active = 0,buttons = 
                                       list(list(method = "restyle",
                                                 args = list("transforms[0].value", unique(eve$year)[1]),
                                                 label = unique(eve$year)[1]),
                                            list(method = "restyle",
                                                 args = list("transforms[0].value", unique(eve$year)[2]),
                                                 label = unique(eve$year)[2]),
                                            list(method = "restyle",
                                                 args = list("transforms[0].value", unique(eve$year)[3]),
                                                 label = unique(eve$year)[3]),
                                            list(method = "restyle",
                                                 args = list("transforms[0].value", unique(eve$year)[4]),
                                                 label = unique(eve$year)[4]),
                                            list(method = "restyle",
                                                 args = list("transforms[0].value", unique(eve$year)[5]),
                                                 label = unique(eve$year)[5])
                                            ))))
    
    fig