Search code examples
rr-plotly

How to set all xaxis dynamically to empty for all levels?


MWE:

# Packages; ####
library(tidyverse)
library(plotly)

# Plot; #####
mtcars %>% 
        group_by(gear,am) %>% 
        summarise(
                mpg = mean(mpg)
        ) %>% do(
                plot = plot_ly(
                        data = .,
                        x = ~gear,
                        y = ~mpg
                ) %>% add_bars(
                        name = ~am
                )
        ) %>% subplot(
                nrows = 1,
                shareY = TRUE,
                shareX = TRUE
        ) %>% layout(
                title = "Facetted Plot",
                xaxis = list(title = "")
        )

This plot has three legends, one for each gear. How do I dynamically set all Xaxis dynamically to "", without having to explicitly specify xaxis = list(title = ""), xaxis1 = list(title = "")?

My own, halfhearted, attempt/idea was to parse and eval inside a function like this,

plot_function <- function(grouping_vars) {
        
        
        # Baseplot; ####
        base_plot = mtcars %>% 
                group_by(!!sym(grouping_vars[1]),!!sym(grouping_vars[2])) %>% 
                summarise(
                        mpg = mean(mpg)
                ) %>% do(
                        plot = plot_ly(
                                data = .,
                                x = ~!!sym(grouping_vars[1]),
                                y = ~mpg
                        ) %>% add_bars(
                                name = ~am
                        )
                ) %>% subplot(
                        nrows = 1,
                        shareY = TRUE,
                        shareX = TRUE
                ) 
        
        # Remove all Xaxis Labels; ####
        
        # Count number of unique values in grouping var;
        no_unique <- mtcars %>%
                select(grouping_vars[1]) %>% 
                unique() %>%
                nrow()
        
        
        gen_layout <- 1:no_unique %>% map(
                .f = function(i) {
                        
                        "some expression here"
                        
                }
        )
        
        

        base_plot %>% 
                gen_layout %>% 
                parse(text = .) %>%
                eval()

        
        
        
}

But I reckon there must be a more elegant solution to this. Preferably a plotly or tidyverse solution if possible!


Solution

  • Not sure whether plotly offers a simple option to achieve that. But one approach would be to write yourself a convenience function to remove (or set the same) title for all x axes:

    # Packages; ####
    library(tidyverse)
    library(plotly)
    
    set_x_axis_title <- function(p, title = "") {
      layout <- p$x$layout
      xaxes <- names(layout)[grepl("^xaxis", names(layout))]
      for (i in xaxes) {
        layout[[i]]["title"] <- title 
      }
      p$x$layout <- layout
      p
    }
    
    # Plot; #####
    mtcars %>% 
      group_by(gear,am) %>% 
      summarise(
        mpg = mean(mpg)
      ) %>% do(
        plot = plot_ly(
          data = .,
          x = ~gear,
          y = ~mpg
        ) %>% add_bars(
          name = ~am
        )
      ) %>% subplot(
        nrows = 1,
        shareY = TRUE,
        shareX = TRUE
      ) %>% layout(
        title = "Facetted Plot"
      ) %>% 
      set_x_axis_title()
    #> `summarise()` has grouped output by 'gear'. You can override using the `.groups` argument.