使用plotly::ggplotly转换ggplot绘图时如何保留两个独立图例
问题原因
ggplotly在转换ggplot对象时,默认会将不同美学映射(本例中是fill和color)的图例项合并到同一个图例组中,因此会丢失第二个图例的标题,出现图例合并的问题。
可行解决方法
通过手动修改ggplotly转换后生成的plotly对象的图例配置,即可拆分出两个独立图例,和原始ggplot的显示效果保持一致,完整代码如下:
library(tidyverse) library(plotly) # 原有生成ggplot对象的代码 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")) # 转换为plotly对象并调整图例 p <- ggplotly(gg) # 配置竖线trace的图例归属 p$x$data[[4]]$name <- "mystatistic" p$x$data[[4]]$legendgroup <- "statistics" p$x$data[[4]]$legend <- "legend2" # 配置两个独立图例的样式 p <- p %>% layout( # 第一个图例对应status 1 legend = list( title = list(text = "status 1"), y = 1, traceorder = "normal" ), # 第二个图例对应statistics legend2 = list( title = list(text = "statistics"), y = 0.7, traceorder = "normal" ) ) # 输出最终图形 p
代码说明
- ggplotly生成的plotly对象中,
p$x$data列表存储了所有图形元素的配置:前3个元素分别对应折线、yes填充区域、no填充区域,第4个元素是geom_vline生成的竖线元素。 - 我们给竖线元素单独指定
legendgroup为statistics,并且指定用legend2(第二个独立图例)展示,即可实现两个图例拆分。 - 可以通过调整两个图例的
y参数调整图例的垂直位置,适配不同的图形布局。
内容的提问来源于stack exchange,提问作者user63230
相关产品推荐
相关产品推荐

