如何用ggplot2和cowplot合并图表并实现轴对齐与geom_rect重叠?
嘿,我之前在处理类似的分组可视化时也踩过轴对齐的坑,下面是我打磨过的完整解决方案,从统计计算到绘图合并都给你安排明白了,直接替换成你的真实数据就能用:
完整实现代码
# 加载所需工具包 library(tidyverse) library(cowplot) # ---------------------- # 1. 数据准备(替换为你的真实数据集) # 模拟示例数据:pk和perio两组数值型数据 set.seed(123) # 固定随机种子,保证结果可复现 pk_data <- tibble(group = "pk", value = rnorm(200, mean = 5, sd = 1.2)) perio_data <- tibble(group = "perio", value = rnorm(250, mean = 7, sd = 1.5)) df <- bind_rows(pk_data, perio_data) # 如果你的数据是宽格式(比如两列分别是pk和perio),用下面的代码转成长格式: # wide_df <- tibble(pk = your_pk_vector, perio = your_perio_vector) # df <- wide_df %>% pivot_longer(cols = everything(), names_to = "group", values_to = "value") # ---------------------- # 2. 计算分组统计量:均值、标准差、95%置信区间 summary_stats <- df %>% group_by(group) %>% summarize( sample_size = n(), mean_value = mean(value), sd_value = sd(value), standard_error = sd_value / sqrt(sample_size), ci_lower = mean_value - qt(0.975, sample_size - 1) * standard_error, ci_upper = mean_value + qt(0.975, sample_size - 1) * standard_error ) # 打印统计结果 print(summary_stats) # ---------------------- # 3. 封装绘图函数(避免重复代码,方便统一调整样式) create_dist_plot <- function(target_group) { # 提取当前分组的原始数据和统计量 group_raw_data <- df %>% filter(group == target_group) group_stats <- summary_stats %>% filter(group == target_group) ggplot(group_raw_data, aes(x = value)) + # 直方图:用density归一化y轴,和密度图匹配 geom_histogram(aes(y = after_stat(density)), bins = 15, fill = "#619CFF", alpha = 0.5, color = "white") + # 密度图:突出分布趋势 geom_density(color = "#00BA38", linewidth = 1) + # 95%置信区间矩形:直观展示区间范围 geom_rect(aes(xmin = group_stats$ci_lower, xmax = group_stats$ci_upper, ymin = 0, ymax = Inf), fill = "#F8766D", alpha = 0.2) + # 均值垂直线:标记中心位置 geom_vline(xintercept = group_stats$mean_value, color = "#F8766D", linewidth = 1.2, linetype = "dashed") + # 标注统计信息:把均值和置信区间直接标在图上 annotate("text", x = group_stats$mean_value, y = max(after_stat(density), data = group_raw_data) * 0.9, label = str_glue("Mean: {round(group_stats$mean_value, 2)}\n95% CI: [{round(group_stats$ci_lower, 2)}, {round(group_stats$ci_upper, 2)}]"), hjust = 0.5, color = "#F8766D") + # 主题美化 theme_minimal() + labs(title = str_glue("{target_group} 数据分布"), x = "数值", y = "密度") + theme(plot.title = element_text(hjust = 0.5)) } # 生成两个分组的可视化图表 pk_plot <- create_dist_plot("pk") perio_plot <- create_dist_plot("perio") # ---------------------- # 4. 合并图表并解决轴对齐问题 # 核心:用cowplot的plot_grid,通过align参数强制对齐坐标轴 combined_plot <- plot_grid(pk_plot, perio_plot, labels = c("A", "B"), # 添加子图标签 ncol = 2, # 横向排列 align = "hv", # 同时对齐水平和垂直方向的轴 axis = "tb") # 指定对齐顶部和底部的轴(垂直排列用"lr") # 如果手动对齐更稳妥,可以先统一x轴范围: # x_limits <- range(df$value) # pk_plot <- pk_plot + xlim(x_limits) # perio_plot <- perio_plot + xlim(x_limits) # 查看最终合并后的图表 print(combined_plot)
关键细节说明
- 统计量计算:用t分布计算95%置信区间(
qt(0.975, n-1)),适合样本量不大的情况;如果你的样本量超过30,也可以用正态分布的qnorm(0.975)代替。 - 绘图逻辑:直方图用
after_stat(density)让y轴和密度图保持一致,方便对比分布形状;置信区间矩形用ymax=Inf覆盖整个y轴,视觉上更清晰。 - 轴对齐解决方案:
plot_grid的align="hv"是核心,它会自动检测两个图的坐标轴范围并对齐;如果还是有偏差,手动设置xlim统一x轴范围是最稳妥的办法。
内容的提问来源于stack exchange,提问作者antecessor
相关产品推荐
相关产品推荐

