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

如何用patchwork实现多图共享点图例且保留各自填充图例?

问题解决:Patchwork多面板图共享指定图例,保留子图填充图例

需求说明

  • 多面板图共享点的**颜色(treat)、形状(top)、透明度(top)**图例
  • 每个子图保留自身的**填充(fill=total)**图例(不同子图的填充数值范围存在差异,需保留特异性)
  • 当前使用plot_layout(guides = "collect")会将所有图例(包括填充图例)收集,导致填充图例重复或丢失子图特异性

解决方案

核心思路是仅收集需要共享的图例类别,让填充图例保留在每个子图中。通过patchwork的collect_guides()函数精准指定要收集的图例(color、shape、alpha),排除填充图例(fill)。

修改后的完整代码

library(ggplot2)
library(dplyr)
library(patchwork)
library(ggrepel)

set.seed(123) # 设置随机种子保证结果可重复
df1 <- data.frame(site = rep(c("a","b","c"),each=10),
                  treat = rep(c("treat_1","treat_2"),each=5),
                  species = rep(c("spA","spB","spC","spD","spE")),
                  val = rpois(30,10))
df1$val2 <- NA
df1$val2[df1$species == "spA"] <- 15
df1$val2[df1$species == "spB"] <- 10
df1$val2[df1$species == "spC"] <- 12
df1$val2[df1$species == "spD"] <- 8
df1$val2[df1$species == "spE"] <- 5
df1$top <- NA
df1$top[df1$species == "spA"] <- "top_1"
df1$top[df1$species == "spB"] <- "top_2"
df1$top[df1$species == "spC"] <- "top_3"
df1$top[df1$species == "spD"] <- "none"
df1$top[df1$species == "spE"] <- "none"

### Contour plot 生成函数
contour_plot <- function(data, site_name) {
  site_data <- data %>% filter(site == site_name)
  
  value_2 <- seq(min(site_data$val2), max(site_data$val2), length.out = 50)
  value_1 <- seq(min(site_data$val), max(site_data$val), length.out = 50)
  
  grid_df <- expand.grid(anomaly = value_2, abun = value_1) %>%
    mutate(total = anomaly * abun)
  
  top_contributors <- site_data %>% 
    filter(top %in% c("top_1", "top_2", "top_3") & treat == "treat_1")
  
  p <- ggplot(grid_df, aes(x = anomaly, y = abun)) +
    geom_tile(aes(fill = total)) +
    geom_contour(aes(z = total), color = "gray50") +
    geom_point(data = site_data, aes(x = val2, y = val, color = treat, alpha = top, shape = top), size=3) +
    scale_alpha_manual(values = c("top_1" = 1, "top_2" = 1, "top_3" = 1, "none" = 0.4),
                       labels = c("top_1" = "Top 1", "top_2" = "Top 2", "top_3" = "Top 3", "none" = "N/A")) +
    scale_shape_manual(values = c("top_1" = 8, "top_2" = 18, "top_3" = 17, "none" = 20),
                       labels = c("top_1" = "Top 1", "top_2" = "Top 2", "top_3" = "Top 3", "none" = "N/A")) +
    scale_fill_gradient2(
      low = "blue", mid = "white", high = "red", midpoint = 0,
      guide = guide_colorbar(title = "Total") # 明确填充图例标题,保证子图显示一致性
    ) +
    ggtitle(site_name) +
    geom_label_repel(data = top_contributors,
                     aes(x = val2, y = val, label = species),
                     size = 3,
                     box.padding = 0.5,
                     point.padding = 0.3,   
                     fill = "white",
                     color = "black",
                     nudge_x = 0.1,
                     nudge_y = 0.0001,  
                     min.segment.length = unit(0, 'lines'),
                     segment.color = 'grey50') +
    theme_minimal() +
    theme(axis.text.x = element_text(size = 12),
          axis.text.y = element_text(size = 14),
          axis.title = element_text(size = 14, face = "bold"),
          legend.position = "right") # 让填充图例显示在子图右侧
  
  p # 返回绘图对象,避免提前输出
}

# 批量生成并存储子图
plots_contours <- lapply(unique(df1$site), function(site) contour_plot(df1, site))

### 多面板图组合:仅收集指定图例
wrap_plots(plots_contours, ncol=2, nrow=2) +
  plot_layout(
    guides = collect_guides(guides = c("color", "shape", "alpha")), # 仅收集点相关的共享图例
    axis_titles = "collect"
  ) +
  plot_annotation(title = "Site-specific Contour Plots", theme = theme(title = element_text(size=16, face="bold"))) # 可选:添加总标题

关键修改点

  1. 子图生成优化:移除print(p),直接返回绘图对象,保证patchwork能正确处理
  2. 填充图例配置:给scale_fill_gradient2添加guide = guide_colorbar(),明确保留子图的填充图例
  3. 图例收集控制:用collect_guides(guides = c("color", "shape", "alpha"))替代全局"collect",精准指定要共享的图例类别,填充图例自动保留在每个子图中
  4. 可重复性保障:添加set.seed(123)保证随机生成的数据可重复

内容的提问来源于stack exchange,提问作者millie0725

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:45:55