goingdeep
goingdeep

Reputation: 121

ggplotly dropdown menu default graph incorrect

    structure(list(Indicator = 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, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 
5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 
5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 
6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 
7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 
7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 
8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 
8L, 8L, 8L, 8L, 8L, 8L), levels = c("Criminalisation of torture under domestic law", 
"Designation of the National Preventive Mechanism (in law)", 
"Existence of National Human Rights Institution that fully complies with Paris Principles", 
"Operationality of the National Preventive Mechanism", "Prohibition of torture in the constitution", 
"Ratification of Optional Protocol (OPCAT)", "Ratification of the UN Convention against Torture", 
"Submission of initial report to CAT"), class = "factor"), Date = c(1984, 
1985, 1987, 1989, 1996, 1997, 2002, 2006, 2007, 2009, 2010, 2011, 
2012, 2013, 2014, 2015, 2017, 2018, 2020, 2022, 2005, 2006, 2007, 
2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 
2019, 2020, 2021, 2023, 2024, 1999, 2000, 2001, 2002, 2003, 2004, 
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 
2016, 2017, 2018, 2019, 2020, 2021, 2022, 2006, 2007, 2008, 2009, 
2010, 2011, 2012, 2013, 2014, 2016, 2017, 2018, 2019, 2020, 2021, 
2022, 2024, 1984, 1985, 1986, 1987, 1988, 1990, 1991, 1992, 1993, 
1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 
2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 
2017, 2018, 2019, 2020, 1996, 2003, 2004, 2005, 2006, 2007, 2008, 
2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 
2021, 1984, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 
1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 
2006, 2007, 2008, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 
2018, 2019, 2020, 2021, 1988, 1989, 1990, 1992, 1993, 1994, 1995, 
1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 
2018, 2019, 2022, 2023, 2024), number = c(2L, 1L, 1L, 1L, 1L, 
2L, 1L, 1L, 1L, 3L, 2L, 1L, 1L, 1L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 
1L, 9L, 3L, 9L, 4L, 6L, 7L, 7L, 5L, 3L, 2L, 5L, 7L, 2L, 1L, 2L, 
1L, 2L, 15L, 7L, 5L, 2L, 5L, 3L, 2L, 3L, 3L, 2L, 3L, 2L, 3L, 
1L, 1L, 2L, 1L, 3L, 3L, 2L, 3L, 4L, 3L, 5L, 1L, 3L, 5L, 7L, 4L, 
4L, 9L, 3L, 7L, 6L, 2L, 7L, 5L, 1L, 1L, 1L, 1L, 21L, 1L, 3L, 
6L, 1L, 3L, 10L, 9L, 5L, 5L, 8L, 8L, 2L, 2L, 4L, 1L, 2L, 5L, 
3L, 3L, 1L, 2L, 6L, 1L, 6L, 7L, 5L, 4L, 2L, 4L, 5L, 3L, 4L, 2L, 
1L, 2L, 5L, 3L, 11L, 11L, 3L, 6L, 7L, 7L, 5L, 4L, 5L, 5L, 4L, 
2L, 5L, 1L, 3L, 1L, 1L, 14L, 13L, 10L, 10L, 7L, 8L, 7L, 8L, 7L, 
7L, 7L, 3L, 6L, 9L, 3L, 5L, 5L, 2L, 5L, 2L, 3L, 1L, 2L, 1L, 2L, 
3L, 1L, 2L, 3L, 2L, 2L, 3L, 3L, 2L, 2L, 1L, 5L, 2L, 12L, 11L, 
6L, 3L, 13L, 3L, 8L, 7L, 6L, 7L, 4L, 1L, 3L, 7L, 1L, 2L, 3L, 
3L, 3L, 4L, 3L, 3L, 3L, 1L, 2L, 3L, 3L, 3L, 1L, 1L, 1L), `Number of States` = c(2L, 
3L, 4L, 5L, 6L, 8L, 9L, 10L, 11L, 14L, 16L, 17L, 18L, 19L, 21L, 
23L, 24L, 25L, 26L, 28L, 2L, 3L, 12L, 15L, 24L, 28L, 34L, 41L, 
48L, 53L, 56L, 58L, 63L, 70L, 72L, 73L, 75L, 76L, 78L, 15L, 22L, 
27L, 29L, 34L, 37L, 39L, 42L, 45L, 47L, 50L, 52L, 55L, 56L, 57L, 
59L, 60L, 63L, 66L, 68L, 71L, 75L, 78L, 83L, 1L, 4L, 9L, 16L, 
20L, 24L, 33L, 36L, 43L, 49L, 51L, 58L, 63L, 64L, 65L, 66L, 67L, 
21L, 22L, 25L, 31L, 32L, 35L, 45L, 54L, 59L, 64L, 72L, 80L, 82L, 
84L, 88L, 89L, 91L, 96L, 99L, 102L, 103L, 105L, 111L, 112L, 118L, 
125L, 130L, 134L, 136L, 140L, 145L, 148L, 152L, 154L, 155L, 2L, 
7L, 10L, 21L, 32L, 35L, 41L, 48L, 55L, 60L, 64L, 69L, 74L, 78L, 
80L, 85L, 86L, 89L, 90L, 1L, 15L, 28L, 38L, 48L, 55L, 63L, 70L, 
78L, 85L, 92L, 99L, 102L, 108L, 117L, 120L, 125L, 130L, 132L, 
137L, 139L, 142L, 143L, 145L, 146L, 148L, 151L, 152L, 154L, 157L, 
159L, 161L, 164L, 167L, 169L, 171L, 1L, 6L, 8L, 20L, 31L, 37L, 
40L, 53L, 56L, 64L, 71L, 77L, 84L, 88L, 89L, 92L, 99L, 100L, 
102L, 105L, 108L, 111L, 115L, 118L, 121L, 124L, 125L, 127L, 130L, 
133L, 136L, 137L, 138L, 139L)), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -204L))

library(dplyr)
library(ggplot2)
library(plotly)

p <- ggplot(plotdf,aes(Date, `Number of States`)) +
      lapply(levels(plotdf$Indicator), \(x) {
    list(geom_col(data = ~ subset(.x, Indicator == x), fill = "#E36360"))
         }) +
  labs(x = NULL,
       y = NULL) +
  theme_classic() +
  theme(panel.background = element_rect(fill = "#F1B5B5"),
        plot.background = element_rect(fill = "#F1B5B5"))
ggplotly(p) %>%
  layout(showlegend = F,
         updatemenus = list(
           list(xanchor = "left",
                y = 1.1,
                active = 4,
                buttons = list(list(method = "restyle",
                                    args = list("visible", c(T, F, F, F, F, F, F, F)),
                                    label = "Criminalisation of torture under domestic law"),
                               list(method = "restyle",
                                    args = list("visible", c(F, T, F, F, F, F, F, F)),
                                    label = "Designation of the National Preventive Mechanism (in law)"),
                               list(method = "restyle",
                                    args = list("visible", c(F, F, T, F, F, F, F, F)),
                                    label = "Existence of National Human Rights Institution that fully complies with Paris Principles"),
                               list(method = "restyle",
                                    args = list("visible", c(F, F, F, T, F, F, F, F)),
                                    label = "Operationality of the National Preventive Mechanism"),
                               list(method = "restyle",
                                    args = list("visible", c(F, F, F, F, T, F, F, F)),
                                    label = "Prohibition of torture in the constitution"),
                               list(method = "restyle",
                                    args = list("visible", c(F, F, F, F, F, T, F, F)),
                                    label = "Ratification of Optional Protocol (OPCAT)"),
                               list(method = "restyle",
                                    args = list("visible", c(F, F, F, F, F, F, T, F)),
                                    label = "Ratification of the UN Convention against Torture"),
                               list(method = "restyle",
                                    args = list("visible", c(F, F, F, F, F, F, F, T)),
                                    label = "Submission of initial report to CAT"))))) %>%
  config(displayModeBar = FALSE)

This code (hope I didn't forget anything) works well but the first plot outputted is wrong, as the bars don't match the values of the data frame for the default Indicator.

wrong values

After using the dropdown menu though, with any Indicator value, the output is correct.

correct values

Being a novice at ggplotly and having modified that code from another SO answer, I don't know what could be wrong. Thanks for your time.

Upvotes: 1

Views: 66

Answers (1)

Kat
Kat

Reputation: 18754

I was incorrect in my comment. Sigh (directed at my own lack of attention to detail). However, here's a fix.

The reason you're not seeing what you expected when you initially plot is because it's showing all of the data, not the selection from the dropdown. It's a bit vague, but in the Plotly reference for active it states that you can designate the view that is active, not the one you want to be active, or initially seen. I find it to be a bit misleading. From the reference, "Determines which button (by index starting from 0) is considered active."

So using the code you've already painstakingly written, I would suggest a fixer function that sets the visibility to match what you've set as the initial view (Prohibition....).

The function:

fixer <- function(plt) {
  plt <- plotly_build(plt)            # ensure build is complete
  vis <- c(F, F, F, F, T, F, F, F)    # from `Prohibition...`
  lapply(1:length(plt$x$data), \(j) { # hide all but first data set
    plt$x$data[[j]]$visible <<- vis[[j]]
  })
  plt     # return updated plot
}

You can chain this function to the end of your plot like so:

ggplotly(p) %>%
  layout(showlegend = F,
         updatemenus = list(
           list(xanchor = "left",
                y = 1.1,
                active = 4,
                buttons = list(list(method = "restyle",
                                    args = list("visible", c(T, F, F, F, F, F, F, F)),
                                    label = "Criminalisation of torture under domestic law"),
                               list(method = "restyle",
                                    args = list("visible", c(F, T, F, F, F, F, F, F)),
                                    label = "Designation of the National Preventive Mechanism (in law)"),
                               list(method = "restyle",
                                    args = list("visible", c(F, F, T, F, F, F, F, F)),
                                    label = "Existence of National Human Rights Institution that fully complies with Paris Principles"),
                               list(method = "restyle",
                                    args = list("visible", c(F, F, F, T, F, F, F, F)),
                                    label = "Operationality of the National Preventive Mechanism"),
                               list(method = "restyle",
                                    args = list("visible", c(F, F, F, F, T, F, F, F)),
                                    label = "Prohibition of torture in the constitution"),
                               list(method = "restyle",
                                    args = list("visible", c(F, F, F, F, F, T, F, F)),
                                    label = "Ratification of Optional Protocol (OPCAT)"),
                               list(method = "restyle",
                                    args = list("visible", c(F, F, F, F, F, F, T, F)),
                                    label = "Ratification of the UN Convention against Torture"),
                               list(method = "restyle",
                                    args = list("visible", c(F, F, F, F, F, F, F, T)),
                                    label = "Submission of initial report to CAT"))))) %>%
  config(displayModeBar = FALSE) %>% fixer()

enter image description here

Upvotes: 1

Related Questions