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

如何将条形图与分面气泡图对齐组合?(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轴长度不一样。可以通过以下操作修复:

  1. 统一两个图中var_two的因子顺序,确保Y轴类别顺序完全一致
  2. 给条形图添加顶部边距,抵消气泡图分面strip的高度
  3. 用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:35:19