ggplot2 geom_area添加标签:标准正态分布区间占比标注问题
R ggplot标准正态分布面积图添加区间占比标签解决方案
以下是完整可运行的修改后代码,可直接实现给每个面积区块添加对应区间占比标签的效果:
library(tidyverse) library(ggplot2) library(magrittr) sim_dat = data.frame(z = seq(-5,5, length.out = 1001)) sim_dat$y = dnorm(sim_dat$z, mean = 0, sd=1) # 填写z-score分位点,0会默认自动加入无需填写 zscores <- c(-1,1.5) zscores <- sort( setdiff(zscores,0) ) bkpoints <- sort( c(-Inf, zscores,0, Inf)) # 计算各区间数据占比+标签坐标 pctdata <- numeric(length=length(bkpoints)-1) interval <- character(length=length(bkpoints)-1) x_mid <- numeric(length=length(bkpoints)-1) # 标签x轴定位:区间中点 y_pos <- numeric(length=length(bkpoints)-1) # 标签y轴定位:色块中心高度 for(i in 1:length(pctdata)){ pctdata[i] <- plyr::round_any( pnorm(q=bkpoints[i+1]) - pnorm(q=bkpoints[i]) , 0.0001) interval[i] <- paste0(bkpoints[i],",",bkpoints[i+1]) # 处理无穷边界的中点取值 left <- bkpoints[i] right <- bkpoints[i+1] x_mid[i] <- case_when( left == -Inf ~ -4.5, right == Inf ~ 4.5, TRUE ~ (left + right)/2 ) # 标签y高度取区间中点对应密度的1/2,刚好落在色块中心 y_pos[i] <- dnorm(x_mid[i])/2 } pctdata_df <- cbind.data.frame(interval,pctdata,x_mid,y_pos,stringsAsFactors=FALSE) sim_dat$standard_normal_sections = cut(sim_dat$z, breaks = bkpoints) p1 <- ggplot2::ggplot(sim_dat, aes(z, y, fill = standard_normal_sections)) + geom_area(alpha = 0.7) + # 加透明度避免遮挡标签 # 新增标签层,关闭全局映射继承避免报错 geom_text(data = pctdata_df, aes(x = x_mid, y = y_pos, label = scales::percent(pctdata, accuracy = 0.01)), inherit.aes = F, size = 4, fontface = "bold") + scale_x_continuous(breaks= c(seq(-5,5,1), zscores)) + labs(x = "Z-score", y = "概率密度", fill = "Z区间") + theme_bw() p1 pctdata_df
适配说明
- 支持任意自定义z分位点输入,程序会自动计算所有区间的标签位置
- 占比自动转为百分比格式,更适配本科统计教学的展示需求
- 可自行调整
geom_text的size、color参数修改标签样式
内容的提问来源于stack exchange,提问作者Ralph Asher
相关产品推荐
相关产品推荐

