在R语言ggplot中按2020年销量排序堆叠面积图并解决年份取整问题
解决ggplot堆叠面积图的两个问题:排序堆叠类别+年份取整
咱一步步来搞定你遇到的这两个ggplot问题:
一、按2020年销量排序堆叠类别(最高的放顶部)
要让堆叠的顺序按2020年销量从高到低排列(最高的在最顶部),核心是把group转换成因子类型,并指定因子水平的顺序——因为ggplot的堆叠顺序完全跟着因子水平走:先出现的水平在底层,后出现的在顶层。具体操作如下:
- 先提取2020年的数据,计算每个group的总销量,然后按销量升序排列(这样销量最高的group会排在最后,对应堆叠顶部):
library(dplyr) # 提取2020年各group的总销量,按升序排序 group_order <- data %>% filter(Year == 2020) %>% group_by(group) %>% summarise(total_sale = sum(Sale)) %>% # 如果你的数据是年度聚合好的,直接用Sale就行,不用sum arrange(total_sale) %>% pull(group) # 提取排序后的group列表
- 把原始数据里的
group转成因子,指定levels为刚才得到的排序结果:
data$group <- factor(data$group, levels = group_order)
这样再画堆叠面积图时,2020年销量最高的group就会在最顶部,其余按销量高低依次往下排。
二、解决年份取整不生效的问题
你说把年份设为整数类型没生效,大概率是两种情况:要么只是转了类型但没聚合数据,要么是x轴刻度还在显示连续值。给你两种解决方案:
方案1:不用修改原始数据,只调整x轴刻度为整数
如果你的数据是按半年(比如2012.5)记录的,但只想让x轴显示整数年份刻度,直接在scale_x_continuous里设置breaks就行:
ggplot(data, aes(x=Year, y=Sale, fill=group)) + geom_area() + scale_x_continuous(breaks = seq(min(floor(data$Year)), max(ceiling(data$Year)), by = 1)) + labs(x = "Year", y = "Sales")
这里floor和ceiling是为了确保刻度覆盖所有年份范围,by=1表示每隔1年显示一个刻度。
方案2:先聚合数据到年度整数,再画图
如果确实需要把年份统一为整数(比如把2012.5归到2012年),那得先对数据按年度和group聚合销量,再画图:
data_annual <- data %>% mutate(Year = as.integer(floor(Year))) %>% # 用floor向下取整,或者round()四舍五入,看你需求 group_by(Year, group) %>% summarise(Sale = sum(Sale)) %>% ungroup() # 用聚合后的数据画图 ggplot(data_annual, aes(x=Year, y=Sale, fill=group)) + geom_area()
这样处理后,年份就完全是整数,画图时x轴自然显示整数刻度。
完整示例代码
把两个需求结合起来,给你一个可直接运行的示例:
library(ggplot2) library(dplyr) # 模拟你的数据(包含半年份和多个group) set.seed(123) data <- expand.grid(Year = seq(2012, 2020, 0.5), group = paste0("Group", 1:9)) %>% mutate(Sale = rnorm(nrow(.), mean = 50, sd = 15)) %>% # 手动让Group9在2020年销量最高,方便测试 mutate(Sale = ifelse(Year == 2020 & group == "Group9", Sale + 100, Sale)) # 按2020年销量排序group group_order <- data %>% filter(Year == 2020) %>% group_by(group) %>% summarise(total_sale = sum(Sale)) %>% arrange(total_sale) %>% pull(group) data$group <- factor(data$group, levels = group_order) # 画图(用方案1调整x轴刻度) ggplot(data, aes(x=Year, y=Sale, fill=group)) + geom_area(alpha = 0.8) + scale_x_continuous(breaks = seq(2012, 2020, 1)) + labs(x = "Year", y = "Sales", fill = "Group") + theme_minimal()
内容的提问来源于stack exchange,提问作者user18948933
相关产品推荐
相关产品推荐

