Search code examples
rr-plotly

Filtering pie graph with plotly, Rmd


I am having a problem with filtering a pie chart. Basically the code I have now creates a list with all the different charts for each of the value i filter.

regPlotsA<-map(unique(SpLC1721A$Reg), ~SpLC1721A%>%
                filter(Reg==.x ) %>%
                plot_ly(labels = ~variable, values = ~value, type = 'pie', frame=~Anno)%>%
                layout(title = .x ,
                       xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
                       yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))%>%
                 animation_opts(
                   redraw = FALSE, frame =3000, transition= 2900
                 )
)

What I need to do is turn this code into something with a dropdown from which the user can select the data observed for a specific Reg value and then plot the relative graphic. I can't apparently do a thing like this on a markdown file, in a ioslides presentation, and I feel so stupid.

[Data that I'm working on][1]

structure(list(X = c("Piemonte", "Valle d'Aosta / Vallée d'Aoste", 
"Liguria", "Lombardia", "Trentino Alto Adige / Südtirol", "Veneto", 
"Friuli-Venezia Giulia", "Emilia-Romagna", "Toscana", "Umbria", 
"Marche", "Lazio", "Abruzzo", "Molise", "Campania", "Puglia", 
"Basilicata", "Calabria", "Sicilia", "Sardegna", "Piemonte", 
"Valle d'Aosta / Vallée d'Aoste", "Liguria", "Lombardia", "Trentino Alto Adige / Südtirol", 
"Veneto", "Friuli-Venezia Giulia", "Emilia-Romagna", "Toscana", 
"Umbria", "Marche", "Lazio", "Abruzzo", "Molise", "Campania", 
"Puglia", "Basilicata", "Calabria", "Sicilia", "Sardegna", "Piemonte", 
"Valle d'Aosta / Vallée d'Aoste", "Liguria", "Lombardia", "Trentino Alto Adige / Südtirol", 
"Veneto", "Friuli-Venezia Giulia", "Emilia-Romagna", "Toscana", 
"Umbria", "Marche", "Lazio", "Abruzzo", "Molise", "Campania", 
"Puglia", "Basilicata", "Calabria", "Sicilia", "Sardegna", "Piemonte", 
"Valle d'Aosta / Vallée d'Aoste", "Liguria", "Lombardia", "Trentino Alto Adige / Südtirol", 
"Veneto", "Friuli-Venezia Giulia", "Emilia-Romagna", "Toscana", 
"Umbria", "Marche", "Lazio", "Abruzzo", "Molise", "Campania", 
"Puglia", "Basilicata", "Calabria", "Sicilia", "Sardegna", "Piemonte", 
"Valle d'Aosta / Vallée d'Aoste", "Liguria", "Lombardia", "Trentino Alto Adige / Südtirol", 
"Veneto", "Friuli-Venezia Giulia", "Emilia-Romagna", "Toscana", 
"Umbria", "Marche", "Lazio", "Abruzzo", "Molise", "Campania", 
"Puglia", "Basilicata", "Calabria", "Sicilia", "Sardegna", "Piemonte", 
"Valle d'Aosta / Vallée d'Aoste", "Liguria", "Lombardia", "Trentino Alto Adige / Südtirol", 
"Veneto", "Friuli-Venezia Giulia", "Emilia-Romagna", "Toscana", 
"Umbria", "Marche", "Lazio", "Abruzzo", "Molise", "Campania", 
"Puglia", "Basilicata", "Calabria", "Sicilia", "Sardegna", "Piemonte", 
"Valle d'Aosta / Vallée d'Aoste", "Liguria", "Lombardia", "Trentino Alto Adige / Südtirol", 
"Veneto", "Friuli-Venezia Giulia", "Emilia-Romagna", "Toscana", 
"Umbria", "Marche", "Lazio", "Abruzzo", "Molise", "Campania", 
"Puglia", "Basilicata", "Calabria", "Sicilia", "Sardegna", "Piemonte", 
"Valle d'Aosta / Vallée d'Aoste", "Liguria", "Lombardia", "Trentino Alto Adige / Südtirol", 
"Veneto", "Friuli-Venezia Giulia", "Emilia-Romagna", "Toscana", 
"Umbria", "Marche", "Lazio", "Abruzzo", "Molise", "Campania", 
"Puglia", "Basilicata", "Calabria", "Sicilia", "Sardegna", "Piemonte", 
"Valle d'Aosta / Vallée d'Aoste", "Liguria", "Lombardia", "Trentino Alto Adige / Südtirol", 
"Veneto", "Friuli-Venezia Giulia", "Emilia-Romagna", "Toscana", 
"Umbria", "Marche", "Lazio", "Abruzzo", "Molise", "Campania", 
"Puglia", "Basilicata", "Calabria", "Sicilia", "Sardegna", "Piemonte", 
"Valle d'Aosta / Vallée d'Aoste", "Liguria", "Lombardia", "Trentino Alto Adige / Südtirol", 
"Veneto", "Friuli-Venezia Giulia", "Emilia-Romagna", "Toscana", 
"Umbria", "Marche", "Lazio", "Abruzzo", "Molise", "Campania", 
"Puglia", "Basilicata", "Calabria", "Sicilia", "Sardegna"), variable = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("vanno.a.piedi", "usano.mezzi.di.trasporto"
), class = "factor"), value = c(13.8, 16.4, 16.2, 8.6, 17.6, 
8.8, 10.2, 9.9, 12.1, 6.9, 7.9, 11.8, 11, 16.3, 18.2, 18, 17.3, 
12.7, 13, 14.8, 84.2, 82.5, 83.5, 89.5, 82.2, 90.6, 89.1, 89.4, 
87.1, 91.7, 91.4, 86.9, 87.8, 82.6, 80.1, 81, 81.8, 85.9, 85.8, 
84.9, 14.3, 21.3, 14.1, 10.3, 14.9, 10.3, 11, 10.9, 11, 9.5, 
9.8, 10.6, 12.6, 13.4, 17.4, 16.5, 13.7, 15.1, 15.4, 12.9, 84.8, 
77.4, 85, 88.7, 84.6, 88.9, 88, 88.7, 87.7, 89.5, 89.3, 87.1, 
86.4, 85.4, 80.6, 81.9, 83.4, 84, 83.3, 86.2, 11.8, 19.9, 17, 
10.5, 15.9, 9.4, 12.1, 9.9, 11.3, 10.8, 10.7, 11.2, 7.7, 13.4, 
17.1, 15.7, 14, 12.6, 12.8, 14.9, 88.2, 80.1, 83, 89.4, 84.1, 
90.6, 87.9, 90.1, 88.7, 89.2, 89.3, 88.8, 92.3, 86.6, 82.9, 84.3, 
86, 87.4, 87.2, 85.1, 12.1, 19.7, 14.4, 9.6, 19, 6.4, 9, 9.7, 
10.7, 9, 11, 9.5, 13.2, 12.5, 20.3, 14.2, 12.8, 16.6, 13.3, 14.9, 
87.9, 80.3, 85.6, 90.4, 81, 93.6, 91, 90.3, 89.3, 91, 89, 90.5, 
86.8, 87.5, 79.7, 85.8, 87.2, 83.4, 86.7, 85.1, 15.1, 20.4, 15.8, 
12.1, 14.2, 7.3, 8.2, 10.7, 9.8, 10.9, 9.4, 11.5, 13.8, 13.7, 
17.2, 17, 15.5, 14, 11.6, 13.1, 84.9, 79.6, 84.2, 87.9, 85.8, 
92.7, 91.8, 89.3, 90.2, 89.1, 90.6, 88.5, 86.2, 86.3, 82.8, 83, 
84.5, 86, 88.4, 86.9), Anno = c(2017, 2017, 2017, 2017, 2017, 
2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 
2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 
2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 
2017, 2017, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 
2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 
2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 
2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2019, 2019, 
2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 
2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 
2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 2019, 
2019, 2019, 2019, 2019, 2019, 2020, 2020, 2020, 2020, 2020, 2020, 
2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 
2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 
2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 
2020, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 
2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 
2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 
2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021)), row.names = c(NA, 
-200L), class = "data.frame")

Solution

  • Updated based on your comment

    I'm assuming that the column named X in your dput output is supposed to be the Reg that you're filtering upon. I changed the name to Reg for this answer.

    This is one of many ways that you can make this work. You could use Plotly to make this dropdown. However, if you're using RMD, I find it a lot easier to use the many other tools available.

    This uses the package shinyRPG, but it's not a Shiny runtime (or anything related to Shiny applications). I'm pretty sure this still isn't a CRAN package. You can get this library with devtools::install_github("RinteRface/shinyRPG").

    I start by creating style tags to hide all of the plots and add a bit of space between the dropdown menu and the plots. Changing the visibility ensures it will only load with one plot initially. (When combined with the rest of the code.) Then I create the dropdown menu and attach an on-change event.

    <style>
    .js-plotly-plot {
      display: none;
      margin: 20px;
    }
    </style>
    
    
    ```{r dropdown}
    library(shinyRPG)
    # create a dropdown menu to change the visibility
    tagDrop  <- rpgSelect("piePlot", "Choose a Pie Chart to Visualize", 
                          setNames(LETTERS[1:length(unique(SpLC1721A$Reg))],
                                   unique(SpLC1721A$Reg)),
                          multiple = F)
    tagDrop$children[[2]]$attribs$onchange <- "getOps(this)"
    tagDrop
    
    ```
    

    Next, I added the graphs.

    ```{r plotters,results='asis'}
    
    htmltools::tagList(map(unique(SpLC1721A$Reg), ~SpLC1721A %>%
                             filter(Reg == .x ) %>%
                             plot_ly(labels = ~variable, values = ~value, 
                                     type = 'pie', frame = ~Anno)%>%
                             layout(title = .x ,
                                    xaxis = list(showgrid = FALSE, zeroline = FALSE,
                                                 showticklabels = FALSE),
                                    yaxis = list(showgrid = FALSE, zeroline = FALSE,
                                                 showticklabels = FALSE))%>%
                             animation_opts(
                               redraw = FALSE, frame =3000, transition= 2900
                             )
    ))
    
    ```
    

    Lastly, I write the code for ensuring the first plot is visible and the on-change event in Javascript. If you run this chunk it won't do anything. You have to knit to execute JS.

    ```{r pickMe,results='asis',engine='js'}
    // for the initial load; show only one pie
    setTimeout(function() {
      picker = document.querySelectorAll('.js-plotly-plot');
      picker[0].style.display = 'block';
    })
    
    // Something selected by user triggers this function
    function getOps(sel) {   
      //get ref to select list and display text box
      graphy = document.querySelectorAll('.js-plotly-plot');
      // loop through selections
      for(i = 0; i < sel.length; i++) {
        opt = sel.options[i];
        if ( opt.selected ) {
          graphy[i].style.display = 'block';
        } else {
          graphy[i].style.display = 'none';
        }
      }
    }
    
    ```
    

    enter image description here

    enter image description here