R Plotly - How to create 2 dropdown menus that both select a part of the data

I am creating an interactive barplot on Plotly (which shows the number of inhabitants - “POPULATION” - concerned by different levels of pollution - “POLLUTION”) .

Here is an extract of my data :

   CITY        TYPE_POLLUANT POLLUTION POPULATION
   <chr>       <chr>             <dbl>      <dbl>
 1 Abriès (05) O3               117             2
 2 Abriès (05) O3               118           225
 3 Abriès (05) O3               119            79
 4 Abriès (05) NO2                0           303
 5 Abriès (05) NO2                1             2
 6 Abriès (05) NO2                2             1

10 Aiglun (04) O3               126           256
11 Aiglun (04) O3               127          1128
12 Aiglun (04) NO2                2            18
13 Aiglun (04) NO2                3           150
14 Aiglun (04) NO2                4           470
15 Aiglun (04) NO2                5           601

I want the barplot to change according to the city selected, or the pollutant selected.

For that, I’m using the updatemenus option.

I achieved to add buttons to select the pollutant (NO2, O3, PM2.5 or PM10), I get something like this :

I also achieved to create a dropdown to select the city, I get that :

But I want both on the barplot, and I don’t achieve that.

I created the first graph (to select pollutants) with this code :

fig <- plot_ly(type = "bar", name='') 

fig <- fig %>% 
  add_bars(data = df %>% filter(NOM_COMMUNE==input_commune, TYPE_POLLUANT=="NO2"),
           x = ~POLLUTION,  y = ~POPULATION,
           name = "NO2", marker=list(color=col_no2)) %>%

  add_bars(data = df %>% filter(NOM_COMMUNE==input_commune, TYPE_POLLUANT=="O3"),
           x = ~POLLUTION,  y = ~POPULATION,
           name = "O3", marker=list(color=col_o3), visible = FALSE) #%>%

  #same for 2 other pollutants

fig <- fig %>%
  layout(updatemenus = list(

    list(
      active = -1,
      type= 'buttons', direction = "right",
      y = 0.92, x=0.95,
      buttons = list(
        list(method = "update",
             args = list(list(visible = c(FALSE, TRUE, FALSE, FALSE, FALSE))),
             label = "NO2"),

        list(method = "update",
             args = list(list(visible = c(FALSE, FALSE, TRUE, FALSE, FALSE))),
             label = "O3")

        #same for 2 other pollutants
      ))))

For the second, to select the city, I used something like that : https://stackoverflow.com/questions/53856624/r-plotly-list-of-dataframe-with-updatemenu (creating a list of cities with for each a list of “visible” parameters (TRUE/FALSE))

But mixing both solutions seems very complex.

I imagined to create a list of list of “visible” parameters (TRUE/FALSE). But have to create a list of 2 buttons in the updatemenus, since I have to set the parameters of location of the buttons on the graph. So it seems complicated to mix “visible” options of pollutants and cities.

Have you an idea of the right way to proceed ?

Thank you !

I don’t think that you are able to use buttons for the pollutants as long as you have pollution on the y-axis. For buttons you would have to put the pollutants on the y-axis by using an add_trace for every single pollutant. In my opinion it would be best to use another filter for the pollutants as you did for the cities.

I used the small data example you provided. I put it into an object called “data”.

This is my suggested code:

fig <- 

 data %>% 
  

  plot_ly(
    type = 'bar', 
    x = ~POLLUTION, 
    y = ~POPULATION,

    transforms = list(
      
      list(
        type = 'filter',
        target = ~CITY,
        operation = '=',
        value = unique(data$CITY)[1]),
        
      list(
        type = 'filter',
        target = ~TYPE_POLLUTANT,
        operation = '=',
        value = unique(data$TYPE_POLLUTANT)[1])
       
      )) %>% 
  

layout(updatemenus = list(

          list(
            type = 'dropdown',
            x = 0.05,
            buttons = apply(as.data.frame(unique(data$CITY)), 1,
                            function(cit) list(method = 'restyle',
                                               args = list('transforms[0].value',cit),
                                               label = cit)
                            )
            ),
              
          list(
            type = 'dropdown',
            buttons = apply(as.data.frame(unique(data$TYPE_POLLUTANT)), 1,
                            function(typo) list(method = 'restyle',
                                                args = list('transforms[1].value',typo),
                                                label = typo)
                            )
            )
          )
       )

fig

It looks like this: