You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Specie列重新排序ggplot分组柱状图的显示顺序

问题描述

我想用ggplot绘制分组柱状图,要求按Specie列排序:先展示sp1的基因型对应的柱状图,然后是sp2,最后是sp3;同时每个物种内的柱状图要按var值降序排列。目前已经画出图表,但顺序不符合要求,以下是我用的代码和数据集:

ggplot(data=data, aes(x=reorder(Genotype, -var) , y=var, fill=Treatment)) +
  geom_bar(stat="identity", position=position_dodge(width=0.85)) +
  scale_fill_manual(values = c('#4850CE','#D37A3E'),
                    labels = c("Control Temperature (CT)","Heat tress (HS)")) +
  geom_errorbar(aes(ymin = var, ymax = var+e,colour=Treatment),
                width=0.75, position = position_dodge(0.85))+
  scale_colour_manual(values=c('#4850CE','#D37A3E'))+
  theme_bw() + labs(x=NULL, y=expression("a. weight"^~g))+
  scale_y_continuous(breaks = seq(0, max(data$var+data$e), length.out = 6),
                     labels = number_format(accuracy = 0.01))+
  geom_text(aes(label = Genotype, y = 0),angle=90, hjust=0, size=3)+
  theme(panel.grid.minor = element_blank(),
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.title.y = element_text(colour = "black", size=8, face="bold"),
        axis.ticks.y = element_line(colour= "black"),
        axis.text.y =element_text(colour="black", size = 8),
        legend.position = c(0.8, 0.92), legend.background = element_blank(),
        legend.key.size = unit(4, 'mm'),
        legend.title = element_blank(),
        legend.text = element_text(size = 8,face="bold"))+
  guides(colour = FALSE)

数据集

GenotypeSpecieTreatmentvare
BGB094sp1CT185.940644.7377
BGB095sp1CT248.227144.7377
BGB097sp2CT162.469644.7377
BGB001sp2CT284.552244.7377
BGB011sp3CT185.535344.7377
BGB048sp3CT219.084644.7377
BGB094sp1HS150.913744.7377
BGB095sp1HS211.0544.7377
BGB097sp2HS123.836644.7377
BGB001sp2HS247.233844.7377
BGB011sp3HS149.691944.7377
BGB048sp3HS184.797844.7377
解决方案

要实现先按Specie排序(sp1→sp2→sp3),再在每个物种内按var降序排列Genotype,需要提前自定义Genotype的因子顺序,而不是仅用reorder函数。

步骤1:预处理数据,确定排序规则

先基于每个基因型的平均var值(覆盖CT和HS两个处理),结合物种顺序确定最终排序:

library(dplyr)

# 计算每个基因型的平均var值,按指定物种顺序+var降序排列
sorted_genotypes <- data %>%
  group_by(Genotype, Specie) %>%
  summarise(mean_var = mean(var), .groups = "drop") %>%
  arrange(factor(Specie, levels = c("sp1", "sp2", "sp3")), desc(mean_var)) %>%
  pull(Genotype)

# 将Genotype转换为因子,指定自定义顺序
data$Genotype <- factor(data$Genotype, levels = sorted_genotypes)

步骤2:修改ggplot代码

把原代码中x=reorder(Genotype, -var)替换为x=Genotype,因为已经提前设置好因子顺序:

ggplot(data=data, aes(x=Genotype, y=var, fill=Treatment)) +
  geom_bar(stat="identity", position=position_dodge(width=0.85)) +
  scale_fill_manual(values = c('#4850CE','#D37A3E'),
                    labels = c("Control Temperature (CT)","Heat stress (HS)")) + # 修正拼写错误tress→stress
  geom_errorbar(aes(ymin = var, ymax = var+e,colour=Treatment),
                width=0.75, position = position_dodge(0.85))+
  scale_colour_manual(values=c('#4850CE','#D37A3E'))+
  theme_bw() + labs(x=NULL, y=expression("a. weight"^~g))+
  scale_y_continuous(breaks = seq(0, max(data$var+data$e), length.out = 6),
                     labels = scales::number_format(accuracy = 0.01))+ # 加scales::前缀避免函数找不到
  geom_text(aes(label = Genotype, y = 0),angle=90, hjust=0, size=3)+
  theme(panel.grid.minor = element_blank(),
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.title.y = element_text(colour = "black", size=8, face="bold"),
        axis.ticks.y = element_line(colour= "black"),
        axis.text.y =element_text(colour="black", size = 8),
        legend.position = c(0.8, 0.92), legend.background = element_blank(),
        legend.key.size = unit(4, 'mm'),
        legend.title = element_blank(),
        legend.text = element_text(size = 8,face="bold"))+
  guides(colour = FALSE)

说明

  • 用平均var值排序,确保每个基因型的整体水平作为排序依据,而非单个处理的数值
  • 通过factor(Specie, levels = c("sp1", "sp2", "sp3"))强制指定物种的展示顺序
  • 因子顺序设置完成后,ggplot会自动按照该顺序绘制柱状图

内容的提问来源于stack exchange,提问作者Ikram Bashir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 01:05:55