ggplot2中geom_ribbon无法正常绘制的问题求助
排查ggplot2中geom_ribbon无法正常绘制的问题
我无法找出ggplot2里geom_ribbon无法正常绘制的原因,以下是相关数据集和绘图代码,请帮忙排查:
数据集
structure(list(row = c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"), month = c("12", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "01", "02"), cumtmean = c(9.4, 7.8, 7.8, 12.6, 14.9, 15.9, 23.5, 25.7, 26.5, 20.7, 19.2, 16.6, NA, NA, NA), cump00tmean = c(2.5, 3.1, 3.9, 6.1, 8.7, 10.6, 17.4, 19.2, 19.9, 16.6, 14.6, 12.4, 2.5, 3.1, 3.9), cump20tmean = c(4.8, 5.1, 5.5, 9.1, 10.5, 12.1, 19.4, 21.7, 22.4, 18.8, 16.4, 13.8, 4.8, 5.1, 5.5), cump40tmean = c(6.1, 5.8, 6.2, 9.8, 11.1, 12.8, 20.7, 22.6, 22.9, 19.9, 17.1, 14.5, 6.1, 5.8, 6.2), cump50tmean = c(6.4, 6, 6.4, 10.1, 11.4, 13.1, 21.2, 22.9, 23.2, 20.4, 17.4, 14.8, 6.4, 6, 6.4), cump60tmean = c(6.8, 6.4, 6.7, 10.5, 11.8, 13.3, 22, 23.2, 23.5, 20.9, 17.9, 15.1, 6.8, 6.4, 6.7), cump80tmean = c(7.4, 7.1, 7.4, 11.7, 12.4, 14.2, 22.8, 24.2, 24.8, 21.8, 18.5, 15.7, 7.4, 7.1, 7.4), cump100tmean = c(9.8, 9.1, 9.8, 14.7, 15.3, 16.1, 26.4, 27.2, 27.4, 24.2, 20.6, 17.4, 9.8, 9.1, 9.8)), class = "data.frame", row.names = c(NA, -15L ))
绘图代码
p <- ggplot2::ggplot(data = plot_data, aes(x = row)) + #ggplot2::geom_point(aes(y = cumtmean), color = "red", na.rm = TRUE) + ggplot2::geom_line(aes(y = cumtmean, group = 1, color = "cumtmean"), na.rm = TRUE) + ggplot2::scale_color_manual( values = c("cumtmean" = "black"), label = paste0("Cumulative seasonal mean temp. (", selected_year, ")"), guide = guide_legend(order = 1)) + ggplot2::geom_ribbon( aes(ymin = cump100tmean, ymax = cump100tmean + 4, fill = ">P100"), alpha = 0.3, color = "#b2182b", linetype = "51", lineend = "round", linejoin = "round") + ggplot2::geom_ribbon( aes(ymin = cump80tmean, ymax = cump100tmean, fill = "P100"), alpha = 0.3, color = "#ef8a62", linetype = "51", lineend = "round", linejoin = "round") + ggplot2::geom_ribbon( aes(ymin = cump60tmean, ymax = cump80tmean, fill = "P80"), alpha = 0.3, color = "#fddbc7", linetype = "51", lineend = "round", linejoin = "round") + ggplot2::geom_ribbon( aes(ymin = cump40tmean, ymax = cump60tmean, fill = "P60"), alpha = 0.3, color = NA, linetype = "51", lineend = "round", linejoin = "round") + ggplot2::geom_ribbon( aes(ymin = cump20tmean, ymax = cump40tmean, fill = "P40"), alpha = 0.3, color = "#d1e5f0", linetype = "51", lineend = "round", linejoin = "round") + ggplot2::geom_ribbon( aes(ymin = cump00tmean, ymax = cump20tmean, fill = "P20"), alpha = 0.3, color = "#67a9cf", linetype = "51", lineend = "round", linejoin = "round") + ggplot2::geom_ribbon( aes(ymin = cump00tmean - 4, ymax = cump00tmean, fill = "P00"), alpha = 0.3, color = "#2166ac", linetype = "51", lineend = "round", linejoin = "round") + ggplot2::scale_fill_manual( values = c(">P100" = "#b2182b", "P100" = "#ef8a62", "P80" = "#fddbc7", "P60" = "#f7f7f7", "P40" = "#d1e5f0", "P20" = "#67a9cf", "P00" = "#2166ac"), breaks = c(">P100", "P100", "P80", "P60", "P40", "P20", "P00"), # To give order labels = c(">P100" = expr(paste("Extrem. hot season (> ", italic(P[100]), ") (", !!ref_start_year, "-", !!ref_end_year, ")")), "P100" = expr(paste("Very hot season (", italic(P[80]), "-", italic(P[95]), ") (", !!ref_start_year, "-", !!ref_end_year, ")")), "P80" = expr(paste("Hot season (", italic(P[60]), "-", italic(P[80]), ") (", !!ref_start_year, "-", !!ref_end_year, ")")), "P60" = expr(paste("Normal season (", italic(P[40]), "-", italic(P[60]), ") (", !!ref_start_year, "-", !!ref_end_year, ")")), "P40" = expr(paste("Cold season (", italic(P[20]), "-", italic(P[40]), ") (", !!ref_start_year, "-", !!ref_end_year, ")")), "P20" = expr(paste("Very cold season (", italic(P[05]), "-", italic(P[20]), ") (", !!ref_start_year, "-", !!ref_end_year, ")")), "P00" = expr(paste("Extrem. cold season (< ", italic(P[00]), ") (", !!ref_start_year, "-", !!ref_end_year, ")")))) + ggplot2::scale_x_discrete( limits = plot_data$row, labels = c( paste0("Dec", (as.numeric(2023) - 1) %% 100), "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", paste0("Jan", (as.numeric(2023) + 1) %% 100), paste0("Feb", (as.numeric(2023) + 1) %% 100) )) + ggplot2::scale_y_continuous( limits = c(min(min(plot_data$cumtmean, na.rm = TRUE), min(plot_data$cump00tmean, na.rm = TRUE) - 4) - 4, max(max(plot_data$cumtmean, na.rm = TRUE), max(plot_data$cump100tmean, na.rm = TRUE) + 4) + 2), breaks = seq(from = round(min(min(plot_data$cumtmean, na.rm = TRUE), min(plot_data$cump00tmean, na.rm = TRUE) - 4) - 4), to = round(max(max(plot_data$cumtmean, na.rm = TRUE), max(plot_data$cump100tmean, na.rm = TRUE) + 4) + 3), by = 5), labels = function(x) paste0(x, "ºC")) + ggthemes::theme_hc(base_size = 15) + ggplot2::theme( plot.title = ggplot2::element_text(hjust = 1, face = "bold", family = "sans", size = 35), plot.subtitle = ggplot2::element_text(hjust = 1, size = 25), legend.background = ggplot2::element_blank(), legend.box.background = ggplot2::element_rect(fill = "white", color = "black", linewidth = 0.75), legend.position = c(0.15, 0.85), legend.spacing = ggplot2::unit(0, "cm"), legend.margin = ggplot2::margin(r = 5, l = 5, b = 5), legend.title = element_blank() )
问题排查与修复
核心问题分析
- 离散x轴的分组缺失:x轴
row是字符型离散变量,geom_ribbon默认会按每个x值单独分组,无法形成连续的带状区域。你给geom_line加了group=1,但所有geom_ribbon都没设置分组,这是导致带状区域无法正常绘制的关键原因。 - 图层顺序错误:当前
geom_line在geom_ribbon之前绘制,会被带状区域完全覆盖,导致线条不可见。 - 未定义变量报错:代码中用到的
selected_year、ref_start_year、ref_end_year三个变量未提前定义,会直接触发报错中断绘图。 - 图例表达式解析问题:使用
expr渲染图例中的数学表达式时,变量解析容易出现异常,导致图例显示错误。
修复后的代码
# 先定义缺失的变量(根据实际需求修改数值) selected_year <- 2023 ref_start_year <- 2000 ref_end_year <- 2020 # 绘图代码修改 p <- ggplot2::ggplot(data = plot_data, aes(x = row)) + # 先绘制所有带状区域,再绘制线条,确保线条在上方 ggplot2::geom_ribbon( aes(ymin = cump100tmean, ymax = cump100tmean + 4, fill = ">P100", group = 1), alpha = 0.3, color = "#b2182b", linetype = "51", lineend = "round", linejoin = "round") + ggplot2::geom_ribbon( aes(ymin = cump80tmean, ymax = cump100tmean, fill = "P100", group = 1), alpha = 0.3, color = "#ef8a62", linetype = "51", lineend = "round", linejoin = "round") + ggplot2::geom_ribbon( aes(ymin = cump60tmean, ymax = cump80tmean, fill = "P80", group = 1), alpha = 0.3, color = "#fddbc7", linetype = "51", lineend = "round", linejoin = "round") + ggplot2::geom_ribbon( aes(ymin = cump40tmean, ymax = cump60tmean, fill = "P60", group = 1), alpha = 0.3, color = NA, linetype = "51", lineend = "round", linejoin = "round") + ggplot2::geom_ribbon( aes(ymin = cump20tmean, ymax = cump40tmean, fill = "P40", group = 1), alpha = 0.3, color = "#d1e5f0", linetype = "51", lineend = "round", linejoin = "round") + ggplot2::geom_ribbon( aes(ymin = cump00tmean, ymax = cump20tmean, fill = "P20", group = 1), alpha = 0.3, color = "#67a9cf", linetype = "51", lineend = "round", linejoin = "round") + ggplot2::geom_ribbon( aes(ymin = cump00tmean - 4, ymax = cump00tmean, fill = "P00", group = 1), alpha = 0.3, color = "#2166ac", linetype = "51", lineend = "round", linejoin = "round") + ggplot2::geom_line(aes(y = cumtmean, group = 1, color = "cumtmean"), na.rm = TRUE) + ggplot2::scale_color_manual( values = c("cumtmean" = "black"), label = paste0("Cumulative seasonal mean temp. (", selected_year, ")"), guide = guide_legend(order = 1)) + ggplot2::scale_fill_manual( values = c(">P100" = "#b2182b", "P100" = "#ef8a62", "P80" = "#fddbc7", "P60" = "#f7f7f7", "P40" = "#d1e5f0", "P20" = "#67a9cf", "P00" = "#2166ac"), breaks = c(">P100", "P100", "P80", "P60", "P40", "P20", "P00"), labels = c(">P100" = bquote("极端暖季 (> " ~ italic(P[100]) ~ ") (" ~ .(ref_start_year) ~ "-" ~ .(ref_end_year) ~ ")"), "P100" = bquote("极暖季 (" ~ italic(P[80]) ~ "-" ~ italic(P[95]) ~ ") (" ~ .(ref_start_year) ~ "-" ~ .(ref_end_year) ~ ")"), "P80" = bquote("暖季 (" ~ italic(P[60]) ~ "-" ~ italic(P[80]) ~ ") (" ~ .(ref_start_year) ~ "-" ~ .(ref_end_year) ~ ")"), "P60" = bquote("正常季 (" ~ italic(P[40]) ~ "-" ~ italic(P[60]) ~ ") (" ~ .(ref_start_year) ~ "-" ~ .(ref_end_year) ~ ")"), "P40" = bquote("冷季 (" ~ italic(P[20]) ~ "-" ~ italic(P[40]) ~ ") (" ~ .(ref_start_year) ~ "-" ~ .(ref_end_year) ~ ")"), "P20" = bquote("极冷季 (" ~ italic(P[05]) ~ "-"
相关产品推荐
相关产品推荐

