ggplot因子型x轴使用geom_vline添加竖线不显示如何解决
解决方案
核心逻辑
因子类型的x轴在ggplot底层是按level顺序对应整数坐标的,第n个level的坐标就是n。你要在两个相邻level的原始数值之间插入竖线,只需要做线性插值计算对应的x轴坐标即可,完全可以批量自动化处理,不需要手动赋值。
可直接复用的批量计算代码
首先编写计算xintercept的通用函数:
# 通用函数:输入目标竖线数值、因子x轴的level对应的原始数值向量,返回对应ggplot x坐标 calc_vline_pos <- function(target_vals, x_level_values) { # x_level_values是因子levels对应的原始数值,按顺序排列,示例中为c(0,1,4,12,40,100,300,1000) sapply(target_vals, function(v) { # 找到目标值落在的区间 interval <- findInterval(v, x_level_values) if(interval == 0 || interval >= length(x_level_values)) { warning(paste0("数值", v, "超出x轴范围,已忽略")) return(NA) } # 线性插值计算位置 left_val <- x_level_values[interval] right_val <- x_level_values[interval + 1] left_pos <- interval right_pos <- interval + 1 return(left_pos + (v - left_val)/(right_val - left_val)) }) }
代入你的场景使用:
library(drc) library(ggplot2) library(data.table) library(tidyverse) con <- c(0,1,4,12,40,100,300,1000, 0,1,4,12,40,100,300,1000,0,1,4,12,40,100,300,1000) Vector <- c(1.2, 1.5, 1.8, 2, 2.7, 3, 3.5, 4,1.2, 1.5, 1.8, 2, 2.7, 3, 3.5, 4,1.2, 1.5, 1.8, 2, 2.7, 3, 3.5, 4) df <- data.frame(Vector, con) VLineValues <- c(25, 26, 27) # 处理数据 dfTemp <- df[1:8,] dfTemp$X = con[1:8] x_level_vals <- unique(dfTemp$X) # 提取因子levels对应的原始数值,顺序和level一致 dfTemp$X <- factor(dfTemp$X, levels = x_level_vals) # 批量计算所有竖线的x坐标 vline_pos <- calc_vline_pos(VLineValues, x_level_vals) # 循环生成3张独立绘图 for(i in seq_along(vline_pos)) { p <- ggplot(dfTemp, aes(x = X, y = Vector))+ ylim(1, 4.5)+ geom_point()+ geom_vline(xintercept = vline_pos[i])+ # 直接传入计算好的位置即可 geom_smooth(method = drm, method.args = list(fct = LL.5()), se = FALSE) print(p) # 可自行添加ggsave逻辑保存图片 }
效果验证
你提到的25、26、27都落在12(第4个level,坐标4)和40(第5个level,坐标5)之间,按函数计算25对应的坐标约为4.46,和你手动估算的4.7基本一致,函数输出为精准插值位置。该方案不会改变x轴的因子属性,不会挤压图形,也不会丢失S型曲线特征。
内容的提问来源于stack exchange,提问作者Norruas
相关产品推荐
相关产品推荐

