ggplot2图层顺序反转:将plot B置于上层并解决刻度报错
问题解决:ggplot2图层顺序报错及上层显示处理
错误原因
两个数据集的time变量类型不统一:
- data_A的
time是有序离散因子,水平为"A", "1", "2", "3" - data_B的
time是连续数值型,取值为1,2,3,4
当先绘制data_B(触发连续x轴尺度)再绘制data_A时,ggplot无法将离散值适配到连续尺度,因此抛出Discrete value supplied to continuous scale错误。
解决方案:统一x轴变量类型
将data_B的数值型time转换为与data_A匹配的有序因子,确保x轴尺度一致,之后即可自由调整图层顺序让data_B显示在上层。
修改后完整代码
library(ggplot2) library(dplyr) # 原始data_A数据 data_A <- data.frame(id=rep(c("1", "2"), each=3*4), time=rep(ordered(c("A", "1", "2", "3"), levels = c("A", "1", "2", "3")),3*2), val_lines=c(0.6, 0.36, 0.15, 0.09, 0.6, 0.35, 0.13, 0.07, 0.6, 0.31, 0.10, 0.05, 0.75, 0.70, 0.30, 0.15, 0.75, 0.65, 0.25, 0.10, 0.75, 0.60, 0.20, 0.05), grp=rep(rep(c("A", "B", "C"), each=4), 2)) # 原始data_B数据处理,关键:统一time类型 time <- as.numeric(rep(seq(1, 4), each = 5)) value1 <- rep(c(0.05, 0.1, 0.11, 0.12, 0.125), times = 4) value2 <- rep(c(0.02, 0.1, 0.12, 0.125, 0.14), times = 4) group <- rep(c("A", "B", "C", "D", "E"), times = 4) one <- data.frame(time, val = value1, group) two <- data.frame(time, val = value2, group) data_B <- bind_rows(one, two, .id = "id") %>% # 将数值time转换为与data_A匹配的有序因子 mutate(time = factor(case_match(time, 1 ~ "A", 2 ~ "1", 3 ~ "2", 4 ~ "3"), levels = c("A", "1", "2", "3"), ordered = TRUE)) # 组合绘图:先画data_A,再画data_B(确保B在上层) combined_plot <- ggplot() + # data_A图层 geom_line(data = data_A, aes(time, val_lines, colour = grp, group = grp)) + geom_point(data = data_A, aes(time, val_lines, colour = grp, group = grp)) + facet_grid(cols = vars(id)) + # data_B图层(后添加的图层在上层) geom_area(data = data_B, alpha = 0.5, aes(x = time, y = val, fill = group)) + scale_fill_brewer(palette = 3) print(combined_plot)
关键说明
- 通过
case_match将data_B的数值time映射为对应离散值,再转为有序因子,保证与data_A的time完全对齐 - ggplot图层遵循后添加则显示在上层的规则,因此先绘制data_A,再绘制data_B即可实现B图层覆盖在A之上
- 若想反过来先画B再画A,此时x轴尺度已统一为离散型,也不会再触发报错
内容的提问来源于stack exchange,提问作者Eric Fail
相关产品推荐
相关产品推荐

