Как удалить дублирующиеся записи легенды с сюжетами()

Как я могу удалить дубликаты в моей легенде при использовании сюжета subplots()?

Вот мой MWE:

library(plotly)
library(ggplot2)
library(tidyr)

mpg %>%
  group_by(class) %>%
  do(p = plot_ly(., x = ~cyl, y = ~displ, color = ~trans, type = 'bar')) %>%
  subplot(nrows = 2, shareX = TRUE, titleX = TRUE) %>%
  layout(barmode = 'stack')

Ответы

Ответ 1

Другой обходной путь с использованием tidyverse. Следующие шаги добавлены в исходный MWE:

  • Преобразуйте столбец trans в коэффициент.
  • Используйте tidyr complete, чтобы заполнить (не NA) фиктивные значения для недостающих уровней факторов в каждой группе class.
  • Выполните настройку предложения M-M от showlegend до TRUE для одной группы и от legendgroup до trans, чтобы связать записи легенды между вспомогательными участками.
library(plotly)
library(tidyverse)

mpg %>%
    mutate_at("trans", as.factor) %>%  
    group_by(class) %>%
    group_map(.f = ~{          
          ## fill missing levels w/ displ = 0, cyl = first available value 
          complete(.x, trans, fill = list(displ = 0, cyl = head(.x$cyl, 1))) %>%
          plot_ly(x = ~cyl, y = ~displ, color = ~trans, colors = "Paired", type = "bar",
              showlegend = (.y == "2seater"), legendgroup = ~trans) %>%
          layout(yaxis = list(title = as.character(.y)), barmode = "stack")
        }) %>%
    subplot(nrows = 2, shareX = TRUE, titleY = TRUE) 

plotly_plot

Ответ 2

plotly не имеет facet, как ggplot2, поэтому он добавляет легенду для каждого subplot или вы можете отключить его для некоторых из них.

Здесь у нас нет слоя со всеми записями ~class и двух графиков без пересечения в class, их комбинация также охватывает все из них. В этом случае мы могли бы установить showlegend на TRUE для этих конкретных графиков и установить его на FALSE для остальных, а также установить legendgroup на trans, чтобы мы получили уникальный, но также полный легенда.

Как я уже сказал, у нас нет такого особого случая. Так что я могу думать о двух возможностях:

  1. Добавление целых данных (дублирование всего кадра данных) и присвоение им класса All. Затем вычерчивайте это вместе с исходными данными, но сохраняйте легенду только для class == All.

  2. Используя ggplot::facet_wrap, а затем ggplotly, чтобы сделать объект plotly. Однако это может вызвать некоторые проблемы с x-axis (сравните объект ggplot с объектами plotly).

library(plotly)
library(ggplot2)

ly_plot <-  . %>% 
             plot_ly(x = ~cyl, y = ~displ, color = ~trans, 
                     type = 'bar', showlegend = ~all(legendC)) %>%
              add_annotations(
              text = ~unique(class),
              x = 0.5,
              y = 1,
              yref = "paper",
              xref = "paper",
              xanchor = "middle",
              yanchor = "top",
              showarrow = FALSE,
              font = list(size = 15))

mpg %>%
  mutate(class= "_All_") %>% 
  rbind(.,mpg) %>% 
  mutate(legendC = (class == "_All_")) %>% 
  group_by(class) %>%
  do(p = ly_plot(.)) %>%
  subplot(nrows = 2, shareX = TRUE, titleX = TRUE) %>%
  layout(barmode = 'stack')

#> Warning in RColorBrewer::brewer.pal(N, "Set2"): n too large, 
#>  allowed maximum for palette Set2 is 8
#> Returning the palette you asked for with that many colors

p <- ggplot(data = mpg, aes(x=cyl, y=displ, fill=trans))+
      geom_bar(stat="identity") +
      facet_wrap(~class)
p  

ggplotly(p) #seems for this we should also set "colour = trans"