如何将条形图与分面气泡图对齐组合?(R语言ggplot2)
问题
想用R的ggplot2和ggpubr包组合两个图:一个是展示各var_two类别对应var_six数值的条形图,另一个是按var_five分面的气泡图。但分面的strip占了额外高度,导致两个图的Y轴(对应var_two)对不齐,求解决办法。
用户原代码:
library("viridis") library("ggpubr") library("ggplot2") mydata <- data.frame(var_one=c("txt_d_p", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_r_p", "txt_r_g", "txt_r_g", "txt_r_g", "txt_r_g", "txt_r_g", "txt_r_g", "txt_r_g", "txt_d_p", "txt_d_g"), var_two=c("a", "b", "c", "d", "e", "f", "g", "h", "I", "j", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "v", "w", "x", "y", "z"), var_three=c(0.46188, 0.31936, 0.01650, 0.63738, 0.79451, 0.00103, 0.69808, 0.61855, 0.11798, 0.74683, 0.00936, 0.60407, 0.31955, 0.45244, 0.45167, 0.99412, 0.15399, 0.58647, 0.76172, 0.24870, 0.78882, 0.99829, 0.12593, 0.89372, 0.32502), var_four=c(29, 0, 4, 8, 22, 48, 3, 14, 36, 49, 20, 46, 4, 29, 5, 1, 40, 31, 1, 4, 37, 50, 44, 26, 24), var_five=c("cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_b", "cat_b"), var_six=c(0.000308449413656507, 0.00495980196203507, 0.0080034708001948, 0.00863825071060852, 0.0080034708001948, 0.00357824635415942, 0.00824743070875437, 0.000709688303818724, 0.0080034708001948, 0.0080034708001948, 0.000308449413656507, 0.0080034708001948, 0.0080034708001948, 0.00360536192691972, 0.0080034708001948, 0.00070428323596321, 0.00360536192691972, 0.00070428323596321, 0.00563842190862566, 0.00357824635415942, 0.00360536192691972, 0.000384834606500262, 0.00824743070875437, 0.00213203535235097, 0.00378753301631295)) bars <- ggplot(mydata, aes(x=var_two, y=var_six)) + geom_bar(stat="identity", fill="#f68060", alpha=.6, width=.4) + coord_flip() + xlab("") + theme_bw() + theme(text=element_text(size=15, face="bold"), legend.position="none", axis.text.y=element_blank()) bubble_tXt <- ggplot(mydata, aes(x=var_four, y=var_two, fill=var_one)) + geom_point(size=abs(log10(mydata$var_three)), alpha=0.5, shape=21, color="black") + scale_size(range = c(.1, 24), name="p-adjusted") + theme(legend.position="right") + ylab("") + xlab("var_four") + guides(fill=guide_legend(override.aes=list(shape=21, size=5))) + theme_bw() + theme(text=element_text(size=15, face="bold"), legend.position="right") + facet_wrap(~var_five) ggarrange(bubble_tXt, bars, common.legend = TRUE, legend = "bottom")
解决方案
方法一:调整两个图的对齐(保留独立图表)
问题出在分面的strip占了顶部空间,导致条形图和气泡图的Y轴长度不一样。可以通过以下操作修复:
- 统一两个图中
var_two的因子顺序,确保Y轴类别顺序完全一致 - 给条形图添加顶部边距,抵消气泡图分面strip的高度
- 用
ggarrange的align="v"参数强制对齐Y轴
修改后的代码:
library("viridis") library("ggpubr") library("ggplot2") mydata <- data.frame(var_one=c("txt_d_p", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_d_g", "txt_r_p", "txt_r_g", "txt_r_g", "txt_r_g", "txt_r_g", "txt_r_g", "txt_r_g", "txt_r_g", "txt_d_p", "txt_d_g"), var_two=c("a", "b", "c", "d", "e", "f", "g", "h", "I", "j", "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "v", "w", "x", "y", "z"), var_three=c(0.46188, 0.31936, 0.01650, 0.63738, 0.79451, 0.00103, 0.69808, 0.61855, 0.11798, 0.74683, 0.00936, 0.60407, 0.31955, 0.45244, 0.45167, 0.99412, 0.15399, 0.58647, 0.76172, 0.24870, 0.78882, 0.99829, 0.12593, 0.89372, 0.32502), var_four=c(29, 0, 4, 8, 22, 48, 3, 14, 36, 49, 20, 46, 4, 29, 5, 1, 40, 31, 1, 4, 37, 50, 44, 26, 24), var_five=c("cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_a", "cat_b", "cat_b"), var_six=c(0.000308449413656507, 0.00495980196203507, 0.0080034708001948, 0.00863825071060852, 0.0080034708001948, 0.00357824635415942, 0.00824743070875437, 0.000709688303818724, 0.0080034708001948, 0.0080034708001948, 0.000308449413656507, 0.0080034708001948, 0.0080034708001948, 0.00360536192691972, 0.0080034708001948, 0.00070428323596321, 0.00360536192691972, 0.00070428323596321, 0.00563842190862566, 0.00357824635415942, 0.00360536192691972, 0.000384834606500262, 0.00824743070875437, 0.00213203535235097, 0.00378753301631295)) # 统一var_two的因子顺序,保证两个图Y轴类别顺序一致 mydata$var_two <- factor(mydata$var_two, levels = rev(unique(mydata$var_two))) bars <- ggplot(mydata, aes(x=var_two, y=var_six)) + geom_bar(stat="identity", fill="#f68060", alpha=.6, width=.4) + coord_flip() + xlab("") + theme_bw() + theme(text=element_text(size=15, face="bold"), legend.position="none", axis.text.y=element_blank(), # 给条形图顶部加边距,抵消气泡图分面strip的高度 plot.margin = margin(t = 22, r = 5, b = 5, l = 5, unit = "pt")) bubble_tXt <- ggplot(mydata, aes(x=var_four, y=var_two, fill=var_one)) + geom_point(size=abs(log10(mydata$var_three)), alpha=0.5, shape=21, color="black") + scale_size(range = c(.1, 24), name="p-adjusted") + ylab("") + xlab("var_four") + guides(fill=guide_legend(override.aes=list(shape=21, size=5))) + theme_bw() + theme(text=element_text(size=15, face="bold"), legend.position="right") + facet_wrap(~var_five) # 用align="v"对齐Y轴,设置宽度比例让布局更协调 ggarrange(bubble_tXt, bars, common.legend = TRUE, legend = "bottom", align = "v", widths = c(2, 0.8))
方法二:把条形图整合到分面气泡图里(单图实现)
如果不想分开两个图,可以直接把条形图放到气泡图的右侧,每个分面都对应完整的条形,彻底解决对齐问题。先安装ggh4x包(运行install.packages("ggh4x")),然后用以下代码:
library("viridis") library("ggplot2") library("ggh4x") # 统一var_two的因子顺序 mydata$var_two <- factor(mydata$var_two, levels = rev(unique(mydata$var_two))) # 绘制整合后的单图 ggplot(mydata) + # 气泡图部分 geom_point(aes(x=var_four, y=var_two, fill=var_one), size=abs(log10(mydata$var_three)), alpha=0.5, shape=21, color="black") + # 右侧条形图部分,把x设为一个大于var_four最大值的固定值 geom_col(aes(x=60, y=var_two, width=8), fill="#f68060", alpha=0.6) + # 可选:给条形图添加数值标签 geom_text(aes(x=60, y=var_two, label=round(var_six, 6)), hjust=0.5, vjust=0.5, size=4, color="black") + scale_size(range = c(.1, 24), name="p-adjusted") + guides(fill=guide_legend(override.aes=list(shape=21, size=5))) + theme_bw() + theme(text=element_text(size=15, face="bold"), legend.position="bottom", axis.text.y=element_text(size=12)) + facet_wrap(~var_five) + # 调整X轴范围,给右侧条形图留出空间 xlim(0, 68) + xlab("var_four | var_six")
这个方法把两种可视化元素放在同一个图里,每个分面都包含气泡和对应的条形,不需要额外组合步骤,对齐完全没问题。
内容的提问来源于stack exchange,提问作者another_rando
相关产品推荐
相关产品推荐

