R中分面网格条形图排序及变化百分比标注问题
解决分面条形图排序、颜色匹配及百分比标注问题
一、修正颜色与图例不匹配问题
你当前的条形颜色和图例顺序不对应,核心问题有两个:
- 数据大小写不一致:原始数据中
Active_period是Last_year(首字母大写),但代码里用的是last_year(全小写),导致因子映射失效。 - 颜色映射顺序错位:
scale_fill_manual的values顺序和limits不匹配,造成颜色对应错误。
修正后的基础代码
library(ggplot2) library(dplyr) library(tidyr) # 统一Active_period的大小写,修正数据中的Last_year为last_year data <- data %>% mutate(Active_period = tolower(Active_period)) # 正确设置因子水平,确保顺序符合需求 data$Active_period <- factor(data$Active_period, levels = c("study_year", "last_year", "this_year")) # 绘制基础图,颜色顺序与因子水平对齐 ggplot(data, aes(count, Name, fill = Active_period)) + geom_col(width = 0.8, position = position_dodge2(width = 0.8, preserve = "single"))+ facet_grid(Time ~ site)+ scale_fill_manual(name = " ", values = c("study_year" ="#5d5c5c", "last_year" = "#333239", "this_year" ="#4475aa"), # 与因子水平顺序完全对应 limits = c("study_year","last_year", "this_year"))+ theme(legend.position = "bottom", axis.text = element_text(size = 11), axis.title = element_text(size = 11, face = "bold"), strip.text.x = element_text(size = 12), strip.text.y = element_text(size = 12), plot.title = element_text(size = 14, face = "bold"), plot.subtitle = element_text(size = 13))
二、实现分面内条形排序
要让每个分面(Time+site组合)里的Name按指定指标排序(比如按this_year的count降序),可以先计算排序规则,再将Name转为因子:
# 按每个Time+site组合,以this_year的count为依据排序Name sorted_names <- data %>% filter(Active_period == "this_year") %>% arrange(Time, site, desc(count)) %>% group_by(Time, site) %>% mutate(Name_order = row_number()) %>% ungroup() %>% select(Name, Time, site, Name_order) # 合并排序规则到原数据,将Name转为对应分面的排序因子 data <- data %>% left_join(sorted_names, by = c("Name", "Time", "site")) %>% group_by(Time, site) %>% mutate(Name = factor(Name, levels = unique(Name[order(Name_order)]))) %>% ungroup() # 重新绘图,开启free_y避免空类别占位 ggplot(data, aes(count, Name, fill = Active_period)) + geom_col(width = 0.8, position = position_dodge2(width = 0.8, preserve = "single"))+ facet_grid(Time ~ site, scales = "free_y")+ scale_fill_manual(name = " ", values = c("study_year" ="#5d5c5c", "last_year" = "#333239", "this_year" ="#4475aa"), limits = c("study_year","last_year", "this_year"))+ theme(legend.position = "bottom", axis.text = element_text(size = 11), axis.title = element_text(size = 11, face = "bold"), strip.text.x = element_text(size = 12), strip.text.y = element_text(size = 12), plot.title = element_text(size = 14, face = "bold"), plot.subtitle = element_text(size = 13))
三、标注条形间变化百分比
以标注this_year相对last_year的变化率为例,先计算百分比,再用geom_text添加标注:
# 转换数据格式,计算变化百分比 percent_data <- data %>% pivot_wider(names_from = Active_period, values_from = count) %>% mutate( # 计算last_year到this_year的变化率,处理除零报错情况 change_last_to_this = ifelse(last_year == 0, NA, ((this_year - last_year)/last_year)*100) ) %>% # 转回长格式,方便与条形位置对齐 pivot_longer(cols = c(study_year, last_year, this_year), names_to = "Active_period", values_to = "count") # 绘图并添加百分比标注 ggplot(data, aes(count, Name, fill = Active_period)) + geom_col(width = 0.8, position = position_dodge2(width = 0.8, preserve = "single"))+ # 在this_year条形右侧标注变化率 geom_text(data = percent_data %>% filter(Active_period == "this_year"), aes(x = count + 10, # 调整x轴偏移量避免重叠 label = ifelse(!is.na(change_last_to_this), paste0(round(change_last_to_this, 1), "%"), "")), position = position_dodge2(width = 0.8), size = 3.5)+ facet_grid(Time ~ site, scales = "free_y")+ scale_fill_manual(name = " ", values = c("study_year" ="#5d5c5c", "last_year" = "#333239", "this_year" ="#4475aa"), limits = c("study_year","last_year", "this_year"))+ theme(legend.position = "bottom", axis.text = element_text(size = 11), axis.title = element_text(size = 11, face = "bold"), strip.text.x = element_text(size = 12), strip.text.y = element_text(size = 12), plot.title = element_text(size = 14, face = "bold"), plot.subtitle = element_text(size = 13))
如果需要标注其他对比(如this_year vs study_year),只需在percent_data中新增对应的计算列即可。
内容的提问来源于stack exchange,提问作者GeoBeez
相关产品推荐
相关产品推荐

