使用geom_ridgeline_gradient时分组变量堆叠问题求助
问题
使用ggridges包的geom_ridgeline_gradient函数绘制带渐变效果的脊线图时,分组变量(社区)直接堆叠在一起,没有像正常脊线图那样相互分离。期望实现各社区分组分离的脊线图,按EPA指定的空气质量指数(AQI)类别颜色展示对应天数的计数。
当前绘图效果:各社区的脊线完全堆叠,无任何间距,无法区分不同社区的分组。
目标效果参考:每个社区作为独立一行,脊线之间留有明显间距,清晰展示各社区不同AQI类别的天数分布(类似ggridges官方示例中的分组分离样式)。
以下是示例数据及原始绘图代码:
library(ggridges);library(tidyverse) #data to generate plot AQIcounts <- data.frame( site_name = rep(c("community1", "community2", "community3"),6), AQI_description = rep(c("Good","Moderate","Unhealthy for Sensitive Groups","Unhealthy","Very Unhealthy","Hazardous"),3), n = c(5472, 661, 65, 78, 30, 16, 282, 23, NA, NA, NA, NA, 3945, 441, 9, 2, NA, NA) ) #set level ordering for AQI_description AQIcounts$AQI_description <- factor(AQIcounts$AQI_description, levels=c("Good", "Moderate", "Unhealthy for Sensitive Groups", "Unhealthy", "Very Unhealthy", "Hazardous")) #set color assignments to factors palette <- c("green","yellow","orange","red","purple","maroon") #create palette names(palette) <- levels(AQIcounts$AQI_description) #set the names of color levels ggpalette <- scale_fill_manual(name = "AQI_description", values = palette) ggplot(AQIcounts, aes(x=AQI_description, y = site_name, height = n, group = site_name, fill = AQI_description)) + geom_ridgeline_gradient() + theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) + ggpalette
解决方案
问题根源
- x轴为分类变量,
geom_ridgeline_gradient默认需要连续型x轴生成连贯脊线,且分类y轴默认无间距,导致各组堆叠。 - 数据中存在
NA值,造成脊线断裂,无法形成完整分组区域。 - 未设置y轴间距扩展参数,社区分组间无留白。
修改后的代码
library(ggridges);library(tidyverse) # 数据处理:替换NA为0,避免脊线断裂 AQIcounts <- data.frame( site_name = rep(c("community1", "community2", "community3"),6), AQI_description = rep(c("Good","Moderate","Unhealthy for Sensitive Groups","Unhealthy","Very Unhealthy","Hazardous"),3), n = c(5472, 661, 65, 78, 30, 16, 282, 23, NA, NA, NA, NA, 3945, 441, 9, 2, NA, NA) ) %>% mutate(n = replace_na(n, 0)) # 替换NA为0 # 设置AQI类别顺序 AQIcounts$AQI_description <- factor(AQIcounts$AQI_description, levels=c("Good", "Moderate", "Unhealthy for Sensitive Groups", "Unhealthy", "Very Unhealthy", "Hazardous")) # 定义颜色映射 palette <- c("green","yellow","orange","red","purple","maroon") names(palette) <- levels(AQIcounts$AQI_description) ggpalette <- scale_fill_manual(name = "AQI类别", values = palette) # 绘图:将分类x转为数值,设置y轴间距,调整脊线缩放 ggplot(AQIcounts, aes(x = as.numeric(AQI_description), y = site_name, height = n, group = site_name, fill = AQI_description)) + geom_ridgeline_gradient(scale = 0.0001) + # scale参数根据数据量级调整,避免脊线过高 # 还原x轴的分类标签 scale_x_continuous(breaks = 1:length(levels(AQIcounts$AQI_description)), labels = levels(AQIcounts$AQI_description)) + # 设置y轴间距,分离各组 scale_y_discrete(expand = expansion(add = c(0.5, 0.5))) + theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) + ggpalette + labs(x = "AQI类别", y = "社区")
关键修改点说明
- 替换NA为0:用
replace_na(n, 0)确保每个社区的所有AQI类别都有高度值,避免脊线断裂。 - x轴转为数值型:
as.numeric(AQI_description)让geom_ridgeline_gradient生成连贯脊线,再通过scale_x_continuous还原分类标签。 - 调整y轴间距:
scale_y_discrete(expand = expansion(add = c(0.5, 0.5)))给每个社区分组添加上下留白,实现分组分离。 - scale参数调整:根据数据量级调整
geom_ridgeline_gradient的scale参数,避免脊线高度超出画布。
内容的提问来源于stack exchange,提问作者Kelly Ireland
相关产品推荐
相关产品推荐

