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

如何用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:24:37