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

ggplot多子图公共图例缺失部分数据类别问题求解

解决公共图例缺失Model C的问题

问题场景

生成三个数据集并合并为mydata:

  • mydata1(model=A)、mydata2(model=B)包含n=1-10的全部数据
  • mydata3(model=C)仅包含n=6-10的数据

使用循环绘制每个n对应的子图,通过ggarrange组合后,n=6-10的子图正常显示Model C的曲线,但顶部公共图例里没有Model C的选项。

原代码如下:

mydata1 <- data.frame("model" = rep("A", 1000), "n" = sample.int(10, 1000, replace = T), "n1" = seq(1,1000), "values" = rnorm(1000))
mydata2 <- data.frame("model" = rep("B", 1000), "n" = sample.int(10, 1000, replace = T), "n1" = seq(1,1000), "values" = rnorm(1000))
mydata3 <- data.frame("model" = rep("C", 500), "n" = c(rep(6,100),rep(7,100),rep(8,100),rep(9,100),rep(10,100)), "n1" = seq(1,500), "values" = rnorm(500))
mydata <- rbind(mydata1, mydata2, mydata3)

fig_list <- list()
for(i in 1:length(sort(unique(mydata$n)))) {
    data <- mydata[which(mydata$n == sort(unique(mydata $n))[i]),]
    fig_list[[i]] <- ggplot2::ggplot(data , aes(x = n1, y = values, colour = model)) +
                      geom_line(size = 0.6) +
                      labs(title = paste0("n = ", sort(unique(mydata$n))[i]), x = "n1", y = "values") +
                      theme(plot.title = element_text(hjust = 0.5, size = 10))  
}

fig_all <- ggpubr::ggarrange(plotlist = fig_list, ncol = 2, nrow = ceiling(length(fig_list)/2), common.legend = TRUE, legend = "top")
ggpubr::annotate_figure(fig_all, top = text_grob(paste0("All the plots are here.")))

问题原因

ggarrange的common.legend参数会提取所有子图共同存在的图例元素。由于n=1-5的子图中没有Model C的数据,ggplot会自动丢弃该水平的图例,最终公共图例只保留了所有子图都有的A和B。

两种可行解决方案

方案一:提前将model转为包含全量水平的因子

在合并数据集后,把model列转为因子并指定所有可能的水平,确保每个子图都会识别到三个model的存在:

mydata <- rbind(mydata1, mydata2, mydata3)
# 指定model的所有水平,强制保留C的图例项
mydata$model <- factor(mydata$model, levels = c("A", "B", "C"))

之后保持原绘图循环不变即可,ggarrange会提取到所有三个水平的图例。

方案二:在每个子图中禁用图例自动丢弃

在ggplot代码中添加scale_colour_discrete(drop = FALSE),强制保留所有存在过的model水平图例,即使当前子图没有对应数据:

fig_list[[i]] <- ggplot2::ggplot(data , aes(x = n1, y = values, colour = model)) +
                  geom_line(size = 0.6) +
                  labs(title = paste0("n = ", sort(unique(mydata$n))[i]), x = "n1", y = "values") +
                  theme(plot.title = element_text(hjust = 0.5, size = 10)) +
                  # 禁用自动丢弃不存在的图例水平
                  scale_colour_discrete(drop = FALSE)

两种方法都能让公共图例同时显示A、B、C三个model的选项,且不影响子图中曲线的正常显示。

内容的提问来源于stack exchange,提问作者Phoebe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 14:53:08