'In an R ggplot2-based plotly plot coloured by group and with average lines, how can I select and deselect the average lines selectively?

I have made a self-contained script and plot on RPubs to illustrate what I want: https://rpubs.com/cr517/plotly_select_average_line

In Manufacturer E data, I want to have a button to deselect the average line. How can I do that?

Script:

library(data.table)
library(ggplot2)
library(htmlwidgets)
library(plotly)

dir_ticket <- '/Users/biomagician/Documents/sandbox/stackoverflow/'

dir_output <- paste0(dir_ticket, 'output/plot')
if (!file.exists(dir_output)) dir.create(dir_output, recursive = TRUE)

nb_timepoints <- 10
manufacturers <- c('Ferrero', 'Procter and Gamble', 'Nestlé', 'Migros', 'Coop')
nb_manufacturers <- length(manufacturers)
products <- c('chocolate spread', 'crisps')
nb_products <- length(products)

food_prices <- data.table::data.table(timepoint = rep(1:nb_timepoints, each = nb_manufacturers * nb_products), manufacturer = LETTERS[1:nb_manufacturers], product = products, price = rnorm(nb_timepoints * nb_manufacturers * nb_products, 5))

p <- ggplot2::ggplot(food_prices, ggplot2::aes(x = timepoint, y = price, group = manufacturer, col = manufacturer, label = product)) +
  ggplot2::geom_point() +
  ggplot2::geom_line() +
  ggplot2::geom_smooth(se = FALSE) +
  ggplot2::stat_summary(ggplot2::aes(group = manufacturer, colour = manufacturer), fun.y = mean, geom = 'line', size = 2) +
  ggplot2::theme_classic()
pPlotly <- plotly::ggplotly(p)
htmlwidgets::saveWidget(pPlotly, file = paste0(dir_ticket, 'output/plot/learn_plotly.html'))
pPlotly

sessionInfo()

Session info:

R version 4.1.2 (2021-11-01)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Catalina 10.15.7

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.1/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] plotly_4.10.0     htmlwidgets_1.5.4 ggplot2_3.3.5     data.table_1.14.2

loaded via a namespace (and not attached):
 [1] jquerylib_0.1.4   pillar_1.7.0      compiler_4.1.2    tools_4.1.2       digest_0.6.29     evaluate_0.14    
 [7] lattice_0.20-45   jsonlite_1.7.3    lifecycle_1.0.1   tibble_3.1.6      gtable_0.3.0      nlme_3.1-153     
[13] viridisLite_0.4.0 mgcv_1.8-38       pkgconfig_2.0.3   rlang_1.0.1       Matrix_1.3-4      cli_3.1.1        
[19] crosstalk_1.2.0   yaml_2.2.2        xfun_0.29         fastmap_1.1.0     knitr_1.37        withr_2.4.3      
[25] dplyr_1.0.7       httr_1.4.2        generics_0.1.2    vctrs_0.3.8       grid_4.1.2        tidyselect_1.1.1 
[31] glue_1.6.1        R6_2.5.1          fansi_1.0.2       rmarkdown_2.11    farver_2.1.0      purrr_0.3.4      
[37] tidyr_1.2.0       magrittr_2.0.2    scales_1.1.1      ellipsis_0.3.2    htmltools_0.5.2   splines_4.1.2    
[43] rsconnect_0.8.25  colorspace_2.0-2  labeling_0.4.2    utf8_1.2.2        lazyeval_0.2.2    munsell_0.5.0    
[49] crayon_1.4.2 


Solution 1:[1]

I've worked it out, you can modify the labels as you see fit. To hid the trace, you'll select the label in the legend (i.e., Average of A, Average of B, etc.)

After creating pPlotly, use this to modify the object, using the library purrr:

map(11:15, 
    .f = function(x){
      nm = pPlotly$x$data[[x]]$name
      pPlotly$x$data[[x]]$name <<- paste0("Average of ", nm)
      g = pPlotly$x$data[[x]]$legendgroup
      pPlotly$x$data[[x]]$legendgroup <<- paste0("Average of ", g)
      pPlotly$x$data[[x]]$showlegend <<- TRUE
    })

Plotly had created legend groups for the lines and points since they had the same label, this changes it. The image on the left has all data visible; the plot on the right has all of the average lines hidden.

enter image description here enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Kat