When I convert a ggplot
with two separate legends to plotly
(using ggplotly
), the two legends merge. Does anyone know how to prevent this?
library(tidyverse)
library(plotly)
df <- data.frame(date =
as.Date(c("01/01/1998", "10/01/1998", "15/01/1998",
"25/01/1998", "01/02/1998", "12/02/1998", "20/02/1998"), "%d/%m/%Y"),
date2 = as.Date(c(NA, "10/01/1998", NA,
NA, NA, NA, NA), "%d/%m/%Y"),
counts = c(12, 10, 2, 24, 15, 1, 14),
yes_no = c("yes", "yes", "yes", "no", "no", "no", "no"))
gg <- ggplot(df, aes(x = date, y = counts)) +
geom_line() +
geom_ribbon(aes(ymin = 0, ymax = counts, fill = yes_no), color = NA, alpha = 0.5) +
ggplot2::scale_fill_brewer(name = "status 1", palette = "Accent") +
geom_vline(mapping = aes(xintercept = as.numeric(date2), col = "mystatistic")) +
scale_color_manual(name = "statistics", values = c("mystatistic" = "red"))
gg
which produces two legends:
but when I convert to plotly
:
ggplotly(gg)
it returns one legend with second legend title missing:
This link is useful to remove the parenthesis and comma from the current plot but that's not the fix I am looking for.
thanks
In general the concept of legends is different in ggplot2
and plotly
.
In ggplot2
legends reflect aesthetics, i.e. for your example you get a legend for the fill
aes and one for the color
aes. Additionally for each legend the legend entries reflect the categories of the variable mapped on the aesthetic.
In contrast, in plotly
versions < 5.15
there is only one legend (while plotly >= 5.15 supports multiple legends, this feature is at present not supported by the plotly
for R package) and each legend entry reflects a trace.
But one option to achieve your desired result would be to use legendgroup
s which allows to collect traces in groups and requires to manipulate the plotly
object, e.g. in the code below I group the traces into two groups which I call fill
and color
(Note: There is also a fourth trace with index 1 reflecting the black geom_line
, which however is not displayed in the legend). Second, we can assign a title to each legend group and finally get rid of the overall legend title.
library(ggplot2)
library(plotly)
gg <- ggplot(df, aes(x = date, y = counts)) +
geom_line() +
geom_ribbon(aes(ymin = 0, ymax = counts, fill = yes_no), color = NA, alpha = 0.5) +
ggplot2::scale_fill_brewer(name = "status 1", palette = "Accent") +
geom_vline(mapping = aes(xintercept = as.numeric(date2), col = "mystatistic")) +
scale_color_manual(name = "statistics", values = c("mystatistic" = "red"))
ggp <- ggplotly(gg)
# Assign the traces to legendgroups
ggp$x$data[[2]]$legendgroup <- "fill"
ggp$x$data[[3]]$legendgroup <- "fill"
ggp$x$data[[4]]$legendgroup <- "color"
# Add titles for the legendgroups
ggp$x$data[[2]]$legendgrouptitle <- list(text = "status 1")
ggp$x$data[[3]]$legendgrouptitle <- list(text = "status 1")
ggp$x$data[[4]]$legendgrouptitle <- list(text = "statistics")
# Remove overall legend title
ggp$x$layout$legend$title <- NULL
ggp