ggplot2堆叠面积图变量未堆叠问题求助
解决堆叠面积图未堆叠的问题
嗨Chloé,你精准地找到了问题根源——数据格式不对!ggplot的堆叠面积图需要「长格式(tidy data)」数据才能正常工作,而你现在用的是每个收入构成占一列的「宽格式」,所以单独加多个geom_area()只会让它们各自从0开始绘制,根本不会堆叠。
下面是具体的解决步骤:
1. 把宽格式数据转成长格式
我们需要把y2、y3、y4这三个构成部分整合到同一列,同时用另一列标记它们的类别。这里用tidyr包的pivot_longer()函数来实现:
# 先加载需要的包 library(ggplot2) library(tidyr) library(wesanderson) # 你的原始数据 x <- c(0,37,74,111,148,185,222,259,269,333,370,407,444,481,518,555,592,629,666,703) y1 <- c(762,780,798,816,834,852,870,887,905,923,941,959,977,995,1013,1024,1032,1010,1017,1024) y2 <- c(rep(272,15),265,255,245,235,225) y3 <- c(477,448,420,391,363,334,305,277,248,219,191,162,133,105,76,47,19,0,0,0) y4 <- c(rep(13,17),0,0,0) bdd <- data.frame(x,y1,y2,y3,y4) # 转换为长格式:只保留收入构成部分,去掉总和y1(后面用线单独画) bdd_long <- bdd %>% select(x, y2, y3, y4) %>% pivot_longer(cols = -x, names_to = "收入构成", values_to = "数值")
转换后的数据结构是:每个x对应3行,分别记录y2、y3、y4的数值和类别,这样ggplot就能识别出哪些是要堆叠的部分。
2. 重写ggplot代码
现在只需要一次geom_area()就能实现堆叠,同时保留你原来的红线(显示最终收入y1):
p3 <- ggplot() + # 堆叠面积图:用转换后的长格式数据 geom_area(data = bdd_long, aes(x = x, y = 数值, fill = 收入构成), position = "stack") + # 最终收入的红线(用原始数据的y1) geom_line(data = bdd, aes(x = x, y = y1, color = "red")) + # 保留你原来的主题设置 theme(panel.background = element_rect(fill = "white", colour = "white", size = 0.5, linetype = "solid"), panel.grid.major = element_line(size = 0.25, linetype = 'solid', colour = "grey"), panel.border = element_blank(), panel.grid.minor = element_blank()) + # 填充色:现在是3个构成部分,所以n=3 scale_fill_manual(values = wes_palette(n=3, name="Moonrise3")) + # 给红线设置清晰的标签 scale_color_manual(values = "red", labels = "最终收入") + # 优化图例标题 labs(fill = "收入构成", color = "") print(p3)
为什么这样能解决问题?
原来的代码中,每个geom_area()都是独立绘制的,每个都从y=0开始,所以它们会互相覆盖而不是堆叠。而长格式数据让ggplot知道:「这些数值属于不同类别,需要把它们的数值累加起来绘制」,自动实现堆叠效果。另外注意我把wes_palette的n改成了3,因为现在只有3个收入构成部分,之前的n=5是多余的~
内容的提问来源于stack exchange,提问作者Chloe_pa
相关产品推荐
相关产品推荐

