如何让ggplot2中置信区间线条延伸至面板边框?
问题:让漏斗图置信区间虚线延伸至面板边框
我用以下R代码生成了漏斗图的95%和99.7%置信区间:
######################## ## create the dataset ## ######################## t=seq(0,1200) lambda=0.02 sigma=sqrt(lambda/t) alpha_95=0.05 z_both_95=qnorm(1-alpha_95/2) lower_bound_95=lambda-z_both_95*sigma upper_bound_95=lambda+z_both_95*sigma alpha_997=0.003 z_both_997=qnorm(1-alpha_997/2) lower_bound_997=lambda-z_both_997*sigma upper_bound_997=lambda+z_both_997*sigma df=data.frame(t,lambda,sigma,lower_bound_95,upper_bound_95,lower_bound_997,upper_bound_997) ############################# ## draw the CI on the plot ## ############################# fp <- ggplot()+ geom_line(aes(x = t, y = lower_bound_95), linetype = "dashed", color="orange", size=0.6, data = df) + geom_line(aes(x = t, y = upper_bound_95), linetype = "dashed", color="orange", size=0.6, data = df) + geom_line(aes(x = t, y = lower_bound_997), linetype = "dashed", color="red", size=0.6, data = df) + geom_line(aes(x = t, y = upper_bound_997), linetype = "dashed", color="red", size=0.6, data = df) + geom_hline(aes(yintercept = lambda), color="limegreen", size=0.6, data = df) + scale_x_continuous(limits = c(0,1200), breaks = seq(0,1200,by=150)) + scale_y_continuous(limits = c(-0.1,0.3),breaks = seq(-0.1,0.3,by=0.05)) + xlab("Total Exposure (Days)") + ylab("Exposure-Adjusted Incicence Rate") + theme_bw() fp
当前效果:置信区间的橙色、红色虚线在x=0附近未延伸至面板左侧边框,仅从x>0的位置开始绘制。
目标效果:让橙色、红色的置信区间虚线像绿色的lambda水平线一样,左右两端都延伸至面板边框。
解决方案
核心问题是原代码中t=seq(0,1200)包含t=0值,计算sigma=sqrt(lambda/t)时会得到无穷大,导致对应置信区间边界值无效,ggplot自动跳过这些无效点,所以虚线无法延伸到左侧边框。下面提供两种可行的修改方式:
方法1:修正数据集,补充边界有效点
从t=1开始生成数据,再手动补充x=0处的边界点(用y轴上下限替代无穷值),确保线条能连接到面板边框:
######################## ## create the dataset ## ######################## t=seq(1,1200) # 避免t=0的无效值 lambda=0.02 sigma=sqrt(lambda/t) alpha_95=0.05 z_both_95=qnorm(1-alpha_95/2) lower_bound_95=lambda-z_both_95*sigma upper_bound_95=lambda+z_both_95*sigma alpha_997=0.003 z_both_997=qnorm(1-alpha_997/2) lower_bound_997=lambda-z_both_997*sigma upper_bound_997=lambda+z_both_997*sigma df=data.frame(t,lambda,sigma,lower_bound_95,upper_bound_95,lower_bound_997,upper_bound_997) # 补充x=0处的点,匹配y轴极限值 df <- rbind( data.frame(t=0, lambda=lambda, sigma=NA, lower_bound_95=-0.1, upper_bound_95=0.3, lower_bound_997=-0.1, upper_bound_997=0.3), df ) ############################# ## draw the CI on the plot ## ############################# fp <- ggplot()+ geom_line(aes(x = t, y = lower_bound_95), linetype = "dashed", color="orange", size=0.6, data = df) + geom_line(aes(x = t, y = upper_bound_95), linetype = "dashed", color="orange", size=0.6, data = df) + geom_line(aes(x = t, y = lower_bound_997), linetype = "dashed", color="red", size=0.6, data = df) + geom_line(aes(x = t, y = upper_bound_997), linetype = "dashed", color="red", size=0.6, data = df) + geom_hline(aes(yintercept = lambda), color="limegreen", size=0.6, data = df) + scale_x_continuous(limits = c(0,1200), breaks = seq(0,1200,by=150)) + scale_y_continuous(limits = c(-0.1,0.3),breaks = seq(-0.1,0.3,by=0.05)) + xlab("Total Exposure (Days)") + ylab("Exposure-Adjusted Incicence Rate") + theme_bw() fp
方法2:用geom_segment手动补全边框连接
直接用geom_segment绘制x=0到首个有效点的线段,配合原有的geom_line,实现完整的延伸效果:
fp <- ggplot(df, aes(x=t))+ # 补全95%置信区间左侧边框连接 geom_segment(aes(x=0, xend=df$t[1], y=-0.1, yend=df$lower_bound_95[1]), linetype="dashed", color="orange", size=0.6) + geom_line(aes(y=lower_bound_95), linetype="dashed", color="orange", size=0.6) + geom_segment(aes(x=0, xend=df$t[1], y=0.3, yend=df$upper_bound_95[1]), linetype="dashed", color="orange", size=0.6) + geom_line(aes(y=upper_bound_95), linetype="dashed", color="orange", size=0.6) + # 补全99.7%置信区间左侧边框连接 geom_segment(aes(x=0, xend=df$t[1], y=-0.1, yend=df$lower_bound_997[1]), linetype="dashed", color="red", size=0.6) + geom_line(aes(y=lower_bound_997), linetype="dashed", color="red", size=0.6) + geom_segment(aes(x=0, xend=df$t[1], y=0.3, yend=df$upper_bound_997[1]), linetype="dashed", color="red", size=0.6) + geom_line(aes(y=upper_bound_997), linetype="dashed", color="red", size=0.6) + geom_hline(aes(yintercept = lambda), color="limegreen", size=0.6) + scale_x_continuous(limits = c(0,1200), breaks = seq(0,1200,by=150)) + scale_y_continuous(limits = c(-0.1,0.3),breaks = seq(-0.1,0.3,by=0.05)) + xlab("Total Exposure (Days)") + ylab("Exposure-Adjusted Incicence Rate") + theme_bw() fp
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

