1

I am looking for some guidance on how to use either facet_grid or subplot in my example below. The desired output would be: a grid of individual bar graphs that have the dropdown faceted by the variable "prac". I tried both subplot() and facet_grid but haven't yet gotten either to create the appropriate output. Below is how I tried to incorporate the facet_grid(). Any tips?

library(tidyverse)
library(plotly)


period <- c('201901', '201901', '201904', '201905')
spec <- c('alpha', 'bravo','bravo', 'charlie')
prac <- c('mine','yours','yours','mine')
c <-  c(5,6,3,8)
e <- c(1,2,4,5)

df <- data.frame(period, spec,prac, c,e)


spec.val <- unique(df$spec)
ggplot(plot_ly(
  df %>% pivot_longer(-c(period, spec, prac)),
  x = ~period, y = ~value, color = ~name,
  type = "bar",
  transforms = list(
    list(
      type = "filter",
      target = ~spec,
      operation = "=",
      value = spec.val[1]))) %>%
  layout(
    updatemenus = list(
      list(
        type = "drowdown",
        active = 0,
        buttons = map(spec.val, ~list(
          method = "restyle",
          args = list("transforms[0].value", .x),
          label = .x))))) + facet_grid(~prac))

EDIT:

I tried to add a loop to create the multiple plots. This doesnt work, but conceptually I think this could solve my problem. Any ideas on what I am doing wrong? The below doesn't generate any output (or errors).

spec.val <- unique(df$spec)
for (p in unique(df$prac)) {
  x <- subset(df, prac == p)
    (plot_ly(
      df %>% pivot_longer(-c(period, spec, prac)),
      x = ~period, y = ~value, color = ~name,
      type = "bar",
      transforms = list(
        list(
          type = "filter",
          target = ~spec,
          operation = "=",
          value = spec.val[1]))) %>%
      layout(
        updatemenus = list(
          list(
            type = "drowdown",
            active = 0,
            buttons = map(spec.val, ~list(
              method = "restyle",
              args = list("transforms[0].value", .x),
              label = .x)))))
      )  
}
cowboy
  • 613
  • 5
  • 20

1 Answers1

1

You could do two separate plots and combine them with subplot:

library(tidyverse)
library(plotly)


period <- c('201901', '201901', '201904', '201905')
spec <- c('alpha', 'bravo','bravo', 'charlie')
prac <- c('mine','yours','yours','mine')
c <-  c(5,6,3,8)
e <- c(1,2,4,5)

df <- data.frame(period, spec,prac, c,e)

spec.val <- unique(df$spec)

df.m <- dplyr::filter(df, prac=="mine") %>% pivot_longer(-c(period, spec, prac)) 
df.y <- dplyr::filter(df, prac=="yours") %>% pivot_longer(-c(period, spec, prac))


p1 <- plot_ly(
    df.m,
    x = ~period, y = ~value, color = ~name,
    type = "bar",
    transforms = list(
        list(
            type = "filter",
            target = ~spec,
            operation = "=",
            value = spec.val[1]))) %>%
    layout(
        updatemenus = list(
            list(
                type = "drowdown",
                active = 0,
                buttons = map(spec.val, ~list(
                    method = "restyle",
                    args = list("transforms[0].value", .x),
                    label = .x)))))

p2 <- plot_ly(
    df.y,
    x = ~period, y = ~value, color = ~name,
    type = "bar",
    transforms = list(
        list(
            type = "filter",
            target = ~spec,
            operation = "=",
            value = spec.val[1]))) %>%
    layout(
        updatemenus = list(
            list(
                type = "drowdown",
                active = 0,
                buttons = map(spec.val, ~list(
                    method = "restyle",
                    args = list("transforms[0].value", .x),
                    label = .x)))))

subplot(p1, p2)

Look here to learn more: Subplot in r with plotly

Edit: More generally, you can generate a list of plots and plot that using subplot:


library(tidyverse)
library(plotly)


period <- c('201901', '201901', '201904', '201905')
spec <- c('alpha', 'bravo','bravo', 'charlie')
prac <- c('mine','yours','yours','mine')
c <-  c(5,6,3,8)
e <- c(1,2,4,5)

df <- data.frame(period, spec, prac, c,e)

spec.val <- unique(df$spec)

getPlots <- function(x){
    df.m <- dplyr::filter(df, prac==x) %>% pivot_longer(-c(period, spec, prac)) 
    plot_ly(
        df.m,
        x = ~period, y = ~value, color = ~name,
        type = "bar",
        transforms = list(
            list(
                type = "filter",
                target = ~spec,
                operation = "=",
                value = spec.val[1]))) %>%
        layout(
            updatemenus = list(
                list(
                    type = "drowdown",
                    active = 0,
                    buttons = map(spec.val, ~list(
                        method = "restyle",
                        args = list("transforms[0].value", .x),
                        label = .x)))))

}

plotlist <- lapply(levels(df$prac), getPlots)

subplot(plotlist)
user12728748
  • 8,106
  • 2
  • 9
  • 14
  • That does work for the example, in my real dataset, the prac variable would have 20 or more unique names, so I wouldnt want to manually create plots for each. Do you think there would be a way to automatically do that with loops or purr::map? – cowboy Mar 13 '20 at 15:27
  • You could put them all in a list and pass that to `subplot`. See edit in the post. – user12728748 Mar 13 '20 at 17:59
  • it works in that it creates 3 separate bar graphs, however it only has 1 drop down for all 3 graphs. The preferred solution would be to independent filter each graph with its own drop down – cowboy Mar 13 '20 at 18:19