如何调整ggplot2中小提琴图的X轴显示顺序?
解决X轴小提琴图顺序问题
你的核心问题在于:X轴使用的是拼接后的pop_count变量,而非population_ID,所以仅修改population_ID的因子顺序不会直接影响X轴排列。你尝试的方向有道理,但需要调整步骤确保pop_count也遵循指定顺序。
最优解决方案
直接基于指定的人群顺序,生成pop_count的因子水平,确保X轴严格按照要求排列:
library(dplyr) library(readxl) library(ggplot2) # 读取数据 variants_dist <- read_excel("path/to/file.xlsm", 10) # 定义想要的人群顺序 pop_order <- c("AFR", "EUR", "MENA", "SAS", "CEA", "SIB", "OCE", "AME") # 统计每个人群的样本量,并将population_ID转为指定顺序的因子 df_var <- variants_dist %>% mutate(population_ID = factor(population_ID, levels = pop_order)) %>% group_by(population_ID) %>% summarise(num = n()) # 绘图:生成pop_count并转为对应顺序的因子 variants_dist %>% mutate(population_ID = factor(population_ID, levels = pop_order)) %>% left_join(df_var) %>% mutate( # 拼接pop_count,同时基于population_ID的因子顺序生成pop_count的因子水平 pop_count = paste0(population_ID, "\n", "n=", num), pop_count = factor(pop_count, levels = paste0(pop_order, "\n", "n=", df_var$num)) ) %>% ggplot(aes(x = pop_count, y = snps, fill = population_ID)) + geom_violin(position = "dodge", trim = FALSE) + geom_boxplot(width = 0.07, color = "black", alpha = 0.6) + scale_fill_manual(values = c( EUR = "dodgerblue2", MENA = "mediumvioletred", SIB = "darkkhaki", CEA = "firebrick2", AFR = "olivedrab2", OCE = "powderblue", SAS = "darksalmon", AME = "plum2" )) + theme_bw() + theme(legend.position = "none") + xlab("")
对你尝试方法的说明
你之前的步骤:
variants_dist <- variants_dist %>% mutate(population_ID=factor(population_ID, levels=c("AFR", "EUR", "MENA", "SAS", "CEA", "SIB", "OCE", "AME"))) variants_dist %>% arrange(population_ID) -> pop_sort
这一步是对的,但后续用forcats::fct_inorder(pop_count)时,需要确保pop_count在排列后的数据集里是按组唯一出现的(即每个组的pop_count只出现一次在排序后的开头),这种方法也能生效,但不如直接指定pop_count的因子水平稳妥——如果数据排列时出现组内重复的pop_count,fct_inorder可能会出现错误的顺序。
关键逻辑
- 先将
population_ID转为指定顺序的因子,确保分组统计时的顺序正确 - 生成
pop_count的因子水平时,直接复用预先定义的人群顺序,结合统计出的样本量,严格对应目标排列
内容的提问来源于stack exchange,提问作者Matteo
相关产品推荐
相关产品推荐

