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

如何绘制以物种为X轴、数量为Y轴的年度分组柱状图?

问题描述

我有如下数据集,想要绘制一幅分组柱状图:将species_capture设为X轴,count设为Y轴,每个物种对应不同年份的独立彩色柱子(部分物种有四年统计数据)。我尝试的代码如下:

ggplot(data = data, aes(x = species_capture, y = count, fill = year)) +
  geom_col(position = "dodge2")

数据集:

data <-
  structure(
    list(
      year = c(
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2020,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2021,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2022,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023,
        2023
      ),
      species_capture = c(
        "aplastodiscus_albosignatus",
        "aplastodiscus_arildae",
        "boana_bandeirantes",
        "boana_faber",
        "bokermannohyla_circumdata",
        "bokermannohyla_hylax",
        "brachycephalus_pitanga",
        "chiasmocleis_cf._atlantica",
        "controle",
        "dendrophryniscus_haddadi",
        "dendropsophus_microps",
        "dendropsophus_minutus",
        "dendropsophus_seniculus",
        "fritziana_ohausi",
        "haddadus_binotatus",
        "hylodes_asper",
        "hylodes_phyllodes",
        "ischnocnema_henselii",
        "ischnocnema_parva",
        "leptodactylus_latrans",
        "ololygon_aff_brieni",
        "ololygon_perpusilla",
        "phrynomedusa_dryade",
        "physalaemus_olfersii",
        "rhinella_icterica",
        "scinax_flavoguttatus",
        "scinax_hayii",
        "vitreorana_uranoscopa",
        "?",
        "adenomera_marmorata",
        "aplastodiscus_albosignatus",
        "aplastodiscus_arildae",
        "aplastodiscus_leucopygius",
        "boana_bandeirantes",
        "boana_faber",
        "boana_pardalis",
        "bokermannohyla_circumdata",
        "bokermannohyla_hylax",
        "brachycephalus_pitanga",
        "controle",
        "cycloramphus_sp.",
        "dendrophryniscus_haddadi",
        "dendropsophus_microps",
        "dendropsophus_minutus",
        "dendropsophus_seniculus",
        "fritziana_fissilis",
        "fritziana_ohausi",
        "haddadus_binotatus",
        "hylodes_asper",
        "hylodes_phyllodes",
        "ischnocnema_henselii",
        "ischnocnema_nigriventris",
        "ischnocnema_parva",
        "leptodactylus_latrans",
        "ololygon_aff_brieni",
        "ololygon_perpusilla",
        "phrynomedusa_dryade",
        "physalaemus_cuvieri",
        "physalaemus_olfersii",
        "proceratophrys_appendiculata",
        "proceratophrys_boiei",
        "rhinella_icterica",
        "rhinella_ornata",
        "scinax_flavoguttatus",
        "scinax_hayii",
        "trachycephalus_imitatrix",
        "vitreorana_uranoscopa",
        "hylodes_phyllodes",
        "ischnocnema_henselii",
        "aplastodiscus_leucopygius",
        "boana_bandeirantes",
        "boana_faber",
        "boana_pardalis",
        "bokermannohyla_circumdata",
        "bokermannohyla_hylax",
        "brachycephalus_pitanga",
        "controle",
        "dendrophryniscus_haddadi",
        "dendropsophus_microps",
        "dendropsophus_minutus",
        "fritziana_fissilis",
        "haddadus_binotatus",
        "hylodes_asper",
        "hylodes_phyllodes",
        "ischnocnema_henselii",
        "ischnocnema_parva",
        "leptodactylus_latrans",
        "ololygon_aff_brieni",
        "ololygon_aff_littoralis",
        "ololygon_perpusilla",
        "phrynomedusa_dryade",
        "physalaemus_olfersii",
        "proceratophrys_appendiculata",
        "proceratophrys_boiei",
        "rhinella_icterica",
        "rhinella_ornata",
        "scinax_flavoguttatus",
        "scinax_hayii",
        "vitreorana_uranoscopa",
        "aplastodiscus_arildae",
        "aplastodiscus_leucopygius",
        "boana_bandeirante",
        "boana_bischoffi",
        "boana_faber",
        "bokermannohyla_circumdata",
        "bokermannohyla_hylax",
        "brachycephalus_nodoterga",
        "brachycephalus_sp",
        "control",
        "dendrophryniscus_haddadi",
        "dendropsophus_minutus",
        "haddadus_binotatus",
        "hylodes_phyllodes",
        "ischnocnema_henselii",
        "ischnocnema_parva",
        "ischnocnema_randorum",
        "ischnocnema_sp",
        "leptodactylus_marmoratus",
        "ololygon_cf_litoralis",
        "ololygon_perpusilla",
        "paratelmatobius_cardosoi",
        "paratelmatobius_poecilogaster",
        "physalaemus_cuvieri",
        "physalaemus_sp",
        "rhinella_icterica",
        "rhinella_ornata",
        "scinax_hayii",
        "vitreorana_uranoscopa"
      ),
      count = c(
        4,
        2,
        11,
        5,
        4,
        8,
        72,
        1,
        3,
        11,
        16,
        11,
        1,
        2,
        3,
        1,
        13,
        16,
        6,
        1,
        5,
        2,
        1,
        21,
        5,
        4,
        15,
        6,
        1,
        1,
        6,
        25,
        21,
        26,
        18,
        1,
        20,
        60,
        742,
        12,
        6,
        142,
        24,
        26,
        1,
        2,
        3,
        9,
        6,
        76,
        116,
        7,
        47,
        2,
        52,
        32,
        4,
        2,
        17,
        1,
        51,
        35,
        5,
        29,
        14,
        1,
        21,
        20,
        20,
        13,
        21,
        10,
        1,
        11,
        34,
        487,
        9,
        71,
        1,
        20,
        2,
        3,
        2,
        57,
        67,
        20,
        4,
        52,
        6,
        26,
        2,
        11,
        1,
        9,
        5,
        2,
        51,
        1,
        3,
        1,
        3,
        10,
        15,
        7,
        9,
        21,
        2,
        1,
        3,
        12,
        27,
        1,
        16,
        16,
        41,
        1,
        3,
        17,
        1,
        2,
        2,
        2,
        1,
        5,
        1,
        7,
        1,
        2
      )
    ),
    row.names = c(NA,-128L),
    class = c("tbl_df", "tbl", "data.frame")
  )
优化解决方案

你的基础代码方向是对的,但有几个细节可以优化,让图表更清晰易用:

  1. 将年份转为因子型:原数据中year是数值,转成因子后,图例和分组会更清晰,避免被当作连续变量处理。
  2. 处理物种名称不一致问题:注意数据里存在名称相近但不同的物种(比如boana_bandeirantes和boana_bandeirante,controle和control),如果是录入错误,建议先统一名称,否则会被当作不同物种显示。
  3. 优化X轴标签显示:物种名称较长,旋转X轴标签可以避免重叠。
  4. 调整柱子间距:使用position_dodge()替代dodge2可以让同物种的柱子更紧凑,同时保证不同物种组之间有足够间距。

完整代码如下:

library(ggplot2)

# 可选:统一物种名称(根据实际情况调整)
data$species_capture[data$species_capture == "boana_bandeirante"] <- "boana_bandeirantes"
data$species_capture[data$species_capture == "control"] <- "controle"

# 将年份转为因子
data$year <- as.factor(data$year)

# 绘制分组柱状图
ggplot(data = data, aes(x = species_capture, y = count, fill = year)) +
  geom_col(position = position_dodge(width = 0.8), width = 0.7) +
  # 旋转X轴标签,避免重叠
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  # 添加标题和轴标签
  labs(
    x = "捕获物种",
    y = "数量",
    fill = "年份",
    title = "不同年份各物种捕获数量对比"
  ) +
  # 可选:使用更美观的配色
  scale_fill_brewer(palette = "Set2")

代码说明

  • position_dodge(width = 0.8):控制同物种柱子的间距,width参数调整柱子本身的宽度,让分组更紧凑。
  • axis.text.x = element_text(angle = 45, hjust = 1):将X轴标签旋转45度,右对齐,避免文字重叠。
  • scale_fill_brewer(palette = "Set2"):使用预设配色,比默认颜色更清晰区分不同年份。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:21:59