如何在分面、坐标翻转且X轴连续的ggplot2图中重排离散Y轴
解决方案:调整分组排序与Y轴显示顺序
看起来你需要解决三个核心问题:让地区按字母序分组、国家按字母序排列,以及让自定义的order列控制Y轴从上到下的顺序(order=1在顶部)。我来一步步帮你修正代码和数据处理逻辑:
1. 核心问题分析
ggplot默认会按照变量的因子层级(levels)来决定显示顺序,所以我们需要先对region和country做因子转换,同时结合order列的优先级来调整国家的排列顺序。另外你之前的group_by报错,是因为错误地传入了单独的字符向量,而非数据框的列名。
2. 数据预处理:修正排序与因子转换
先对数据做排序和因子转换,确保地区、国家的顺序符合要求:
library(dplyr) # 处理城市数据:按地区字母序、国家字母序、order升序排列 rdatacities_sorted <- rdatacities %>% arrange(region, country, order) %>% mutate( # 地区按字母序设置因子层级 region = factor(region, levels = unique(sort(region))), # 国家按排序后的顺序设置因子层级,确保order小的排在前面(coord_flip后在顶部) country = factor(country, levels = unique(country)) ) # 同步处理国家数据的region因子,确保与城市数据的facet分组匹配 rdatanations_sorted <- rdatanations %>% mutate(region = factor(region, levels = levels(rdatacities_sorted$region)))
3. 修正group_by的错误写法
你之前的group_by(rdatacities$region, rdatacities$country)报错,是因为传入的是独立的字符向量而非数据框列名。正确的写法是在dplyr管道中直接使用列名:
# 如果需要按贡献值排序的正确写法示例 rdatacities_sorted <- rdatacities %>% group_by(region, country) %>% arrange(desc(contribution), .by_group = TRUE) %>% # 按组内贡献值降序 ungroup() %>% mutate( region = factor(region, levels = unique(sort(region))), country = factor(country, levels = unique(country)) )
4. 完整修正后的绘图代码
将处理好的数据代入ggplot,同时保留你原有的样式设置:
library(readxl) library(grid) library(scales) library(ggplot2) library(dplyr) # --- 数据预处理 --- rdatacities_sorted <- rdatacities %>% arrange(region, country, order) %>% mutate( region = factor(region, levels = unique(sort(region))), country = factor(country, levels = unique(country)) ) rdatanations_sorted <- rdatanations %>% mutate(region = factor(region, levels = levels(rdatacities_sorted$region))) # --- 绘图代码 --- p <- ggplot(rdatacities_sorted, aes(x = country, y = target, size = citiesorig)) + geom_point(shape = 21, alpha = .6, stroke = .75) + # 城市目标点 facet_grid(region ~ ., scales = "free_y", space = "free_y") + # 按地区分组,Y轴自适应空间 geom_point(data = rdatanations_sorted, shape = 0, size = 2.5, stroke = 1, aes(colour = 'red')) + # 国家目标点 theme( plot.title = element_text(hjust = 0.5), legend.key = element_rect(fill = 'white'), panel.background = element_blank(), plot.margin = margin(2), axis.ticks.y = element_blank(), panel.grid.major.y = element_line(size = .2, linetype = 'solid', colour = 'grey'), axis.text.y = element_text(size = 6), panel.grid.major.x = element_blank(), axis.line.x = element_blank(), axis.ticks.x = element_line(color = 'black'), strip.background = element_rect(fill = NA, size = 0, color = "white", linetype = "blank"), # 可选:调整地区分组的间距 panel.spacing = unit(0.1, "cm") ) + scale_y_continuous(name = "Target by 2030 as Percent of Base Year", labels = percent) + scale_x_discrete(name = "Country", expand = waiver()) + coord_flip(ylim = c(0, 3)) + ggtitle("National vs. Municipal GHG Emissions Targets") + guides(colour = guide_legend(order = 1, "Targets"), size = guide_legend(order = 2,"Municipal")) + scale_color_manual(name = "Targets", labels = c("National"), values = c('#843C0C')) print(p)
关键说明
- 地区字母序:通过
factor(region, levels = unique(sort(region)))将地区的因子层级设置为字母排序后的结果,facet会按这个顺序显示分组。 - Y轴顺序控制:先按
order升序排序再转因子,确保order=1的国家在coord_flip后显示在Y轴顶部,同时保留国家的字母序。 - 图表比例问题:你之前尝试的
aspect.ratio和coord_fixed是调整整体宽高比的,与排序无关。当前代码中space = "free_y"已经让每个地区的Y轴空间自适应,若需更紧凑布局可调整panel.spacing参数。
内容的提问来源于stack exchange,提问作者Glen Pierce
相关产品推荐
相关产品推荐

