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

如何用ggplot绘制单因子列条形图并实现降序排序?

解决ggplot条形图绘制与降序排序问题

一、修正基础绘图代码的错误

你最初的代码存在几个语法和逻辑问题:

  • count(tiering$Phenotype)不能直接放在aes()的y参数里,ggplot需要数据框的列作为映射值
  • theme bw()应为theme_bw()(函数名需连写)
  • geom bar()应为geom_bar()(函数名需连写)

推荐两种正确的基础绘图方式:

方式1:先统计数据再绘图

提前统计每个病症的人数,生成新的数据框后再传入ggplot:

library(dplyr)
library(ggplot2)

# 统计各病症的人数
tiering_counts <- tiering %>% 
  count(Phenotype, name = "count")

# 绘制条形图
ggplot(tiering_counts, aes(x = Phenotype, y = count)) +
  geom_bar(stat = "identity") +
  theme_bw()

方式2:使用ggplot自带的统计功能

无需提前统计,让ggplot自动计算每组人数:

library(ggplot2)

ggplot(tiering, aes(x = Phenotype)) +
  geom_bar() + # 默认stat="count",自动计算每组数量
  theme_bw()

二、实现条形按人数降序排序

条形排序失败的核心原因是:Phenotype是因子列,默认按原有因子水平顺序绘制,而非人数顺序。以下两种方法可以解决:

方法1:修改因子水平顺序(推荐)

先统计并排序数据,再将Phenotype的因子水平设置为排序后的顺序:

library(dplyr)
library(ggplot2)

# 统计并按人数降序排列
tiering_counts <- tiering %>% 
  count(Phenotype, name = "count") %>% 
  arrange(desc(count))

# 重置因子水平,按排序后的顺序排列
tiering_counts$Phenotype <- factor(tiering_counts$Phenotype, levels = tiering_counts$Phenotype)

# 绘图(添加x轴标签旋转,避免长名称重叠)
ggplot(tiering_counts, aes(x = Phenotype, y = count)) +
  geom_bar(stat = "identity") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

方法2:使用forcats包动态调整顺序

无需修改原始数据,直接在aes()中用fct_reorder指定排序规则:

library(ggplot2)
library(forcats)

# 针对提前统计的数据框
ggplot(tiering_counts, aes(x = fct_reorder(Phenotype, count, .desc = TRUE), y = count)) +
  geom_bar(stat = "identity") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  xlab("Phenotype") # 修正x轴标签名称

# 针对原始数据框(用stat_count的情况)
ggplot(tiering, aes(x = fct_reorder(Phenotype, Phenotype, .fun = length, .desc = TRUE))) +
  geom_bar() +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  xlab("Phenotype")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 08:30:47