Как удалить дублирующиеся записи легенды с сюжетами()
Как я могу удалить дубликаты в моей легенде при использовании сюжета 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)
Ответ 2
plotly
не имеет facet
, как ggplot2
, поэтому он добавляет легенду для каждого subplot
или вы можете отключить его для некоторых из них.
Здесь у нас нет слоя со всеми записями ~class
и двух графиков без пересечения в class
, их комбинация также охватывает все из них. В этом случае мы могли бы установить showlegend
на TRUE
для этих конкретных графиков и установить его на FALSE
для остальных, а также установить legendgroup
на trans
, чтобы мы получили уникальный, но также полный легенда.
Как я уже сказал, у нас нет такого особого случая. Так что я могу думать о двух возможностях:
Добавление целых данных (дублирование всего кадра данных) и присвоение им класса All
. Затем вычерчивайте это вместе с исходными данными, но сохраняйте легенду только для class == All
.
Используя 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"