如何绘制以物种为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") )
优化解决方案
你的基础代码方向是对的,但有几个细节可以优化,让图表更清晰易用:
- 将年份转为因子型:原数据中
year是数值,转成因子后,图例和分组会更清晰,避免被当作连续变量处理。 - 处理物种名称不一致问题:注意数据里存在名称相近但不同的物种(比如
boana_bandeirantes和boana_bandeirante,controle和control),如果是录入错误,建议先统一名称,否则会被当作不同物种显示。 - 优化X轴标签显示:物种名称较长,旋转X轴标签可以避免重叠。
- 调整柱子间距:使用
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
相关产品推荐
相关产品推荐

