如何移除ggplot2中geom_col列间黑线但保留分块轮廓?
问题描述
我绘制了堆叠柱形图,希望移除geom_col中各堆叠部分之间的黑色分隔线,但保留wild、landrace这类分组块的整体轮廓。基于我当前的代码是否可以实现该需求?
对应的图表效果:
当前使用的示例代码:
library(ggplot2) library(forcats) ggplot(tbl2, aes(factor(sampleID), value, fill=comp)) + geom_col(color="black", size=0.1, width=1) + facet_grid(~fct_inorder(variety), switch="x", scales="free", space="free") + theme_minimal() + labs(x="Individuals", title="K=3", y="components") + scale_y_continuous(expand=c(0, 0)) + scale_x_discrete(expand=expand_scale(add=1)) + theme( panel.spacing.x=unit(0.1, "lines"), axis.text.x=element_blank(), panel.grid=element_blank() ) + scale_fill_brewer(palette="Paired", guide='none')
数据tbl2的结构:
structure(list(sampleID = c("INLUP00165", "INLUP00165", "INLUP00165", "INLUP00169", "INLUP00169", "INLUP00169", "INLUP00208", "INLUP00208", "INLUP00208", "INLUP00214", "INLUP00214", "INLUP00214", "INLUP00228", "INLUP00228", "INLUP00228", "INLUP00233", "INLUP00233", "INLUP00233", "INLUP00245", "INLUP00245", "INLUP00245", "INLUP00325", "INLUP00325", "INLUP00325", "INLUP00332", "INLUP00332", "INLUP00332", "INLUP00393", "INLUP00393", "INLUP00393", "INLUP00418", "INLUP00418", "INLUP00418", "INLUP00496", "INLUP00496", "INLUP00496"), variety = c("wild", "wild", "wild", "landrace", "landrace", "landrace", "wild", "wild", "wild", "wild", "wild", "wild", "landrace", "landrace", "landrace", "wild", "wild", "wild", "landrace", "landrace", "landrace", "landrace", "landrace", "landrace", "landrace", "landrace", "landrace", "landrace", "landrace", "landrace", "landrace", "landrace", "landrace", "landrace", "landrace", "landrace"), comp = c("comp1", "comp2", "comp3", "comp1", "comp2", "comp3", "comp1", "comp2", "comp3", "comp1", "comp2", "comp3", "comp1", "comp2", "comp3", "comp1", "comp2", "comp3", "comp1", "comp2", "comp3", "comp1", "comp2", "comp3", "comp1", "comp2", "comp3", "comp1", "comp2", "comp3", "comp1", "comp2", "comp3", "comp1", "comp2", "comp3"), value = c(0.000304534914903343, 0.999695539474487, 5.66402567378596e-16, 7.25639850429616e-08, 0.99999988079071, 7.41350128733039e-16, 2.27430740759918e-42, 1, 1.40129846432482e-45, 0, 1, 1.26116861789234e-44, 1, 3.6168054052767e-30, 6.73797980640088e-16, 7.37646416837379e-07, 0.999999284744263, 1.86443519971077e-23, 1, 2.82813122498233e-29, 4.54367988546311e-14, 6.76272702548886e-06, 1.06498683288686e-43, 0.999993205070496, 0, 1, 0, 3.04290442727506e-05, 4.66462843997956e-16, 0.999969601631165, 4.25612745047488e-09, 1, 5.97792615408821e-09, 1.18218178221686e-16, 1, 3.16024730889457e-37)), class = "data.frame", row.names = c(NA, -36L))
解决方案
可以实现,只需调整代码的两个核心部分:
- 移除堆叠柱形内部的分隔线:去掉
geom_col中的color="black"参数,让堆叠块之间无黑色线条。 - 添加分组整体轮廓:通过
geom_rect为每个variety分组绘制外框,需要先计算每个分组对应的x轴范围。
修改后的完整代码:
library(ggplot2) library(forcats) library(dplyr) # 计算每个variety分组的x轴起始和结束位置 group_bounds <- tbl2 %>% distinct(sampleID, variety) %>% group_by(variety) %>% mutate(n = n(), x_start = 0.5, # 离散x轴刻度以整数为中心,外框起始设为0.5 x_end = n + 0.5) %>% # 外框结束位置为样本数量+0.5 distinct(variety, x_start, x_end) ggplot(tbl2, aes(factor(sampleID), value, fill=comp)) + # 绘制堆叠柱形,移除内部分隔线 geom_col(color=NA, width=1) + # 为每个分组添加黑色外框 geom_rect(data=group_bounds, aes(xmin=x_start, xmax=x_end, ymin=0, ymax=1), inherit.aes=FALSE, color="black", size=0.1, fill=NA) + facet_grid(~fct_inorder(variety), switch="x", scales="free", space="free") + theme_minimal() + labs(x="Individuals", title="K=3", y="components") + scale_y_continuous(expand=c(0, 0)) + scale_x_discrete(expand=expand_scale(add=1)) + theme( panel.spacing.x=unit(0.1, "lines"), axis.text.x=element_blank(), panel.grid=element_blank() ) + scale_fill_brewer(palette="Paired", guide='none')
关键说明
geom_col(color=NA):将堆叠柱形的边框设为透明,彻底移除内部堆叠块之间的黑色分隔线。geom_rect:基于提前计算的分组x轴范围,绘制仅带黑色边框的空心矩形,刚好包围整个分组的所有柱形,实现分组整体轮廓的效果。
这样就能达到你想要的效果:堆叠部分无内部分隔线,每个wild/landrace分组有完整的外框轮廓。
内容的提问来源于stack exchange,提问作者Matteo
相关产品推荐
相关产品推荐

