You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 09:42:02