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

如何在for循环中绘制并排列多幅ggplot散点图

批量绘制散点图并合并为单张图片的解决方案

数据集

现有数据集filtered_el如下:

filtered_el <- structure(list(Site = c("Cave", "Cave", "Cave", "Cave", "Cave", "Cave", "Open_air", "Open_air", "Cave", "Cave"),
                              Sample = c("s13", "s16", "s20", "s57", "s58", "s59", "s105", "s106", "s110", "s112"),
                              Ca = c(233483.7, 332549.4, 163451.6, 122560.3, 137458, 130964.9, 145151.6, 182335.1, 287127.3, 346025.4),
                              P = c(6653.86, 24779.57, 4747.33, 5875.81, 6670.85, 4770.85, 5607.23, 4101.98, 31762.59, 121520.34),
                              Si = c(85458.49, 53839.66, 91317.05, 166865.47, 107911.59, 113553.15, 151926.88, 123296.37, 79184.64, 20302.76),
                              Mg = c("6822.14", "6446.35", "< LOD", "8755.55", "11751.76", "11785.28", "5124", "7797.72", "7702.34", "< LOD"),
                              Sr = c(236.12, 194.78, 169.51, 98.73, 98.94, 89.14, 315.54, 506.27, 160.78, 247.24),
                              Fe = c(25002.51, 18383.66, 31466.12, 56692.94, 42549.91, 41131.11, 28692.23, 24175.82, 24570.66, 6798.99),
                              K = c(9914.3, 7091.86, 7770.19, 7945.62, 5910.46, 5646.92, 6454.71, 6372.62, 7442.22, 1972.5),
                              Al = c(16847.06, 12103.81, 17776.28, 38946.29, 28895.68, 30437.12, 20931.17, 13815.11, 20492.54, 6099.5)),
                         class = "data.frame", row.names = c(NA, -10L))

需求说明

需要为Ca、P、Si、Mg、Sr、Fe、K、Al8个变量分别绘制散点图(x轴为Sample,y轴为对应变量,按Site区分点的颜色),并将所有图合并为一张图片。现有循环代码仅能逐个输出图片,无法完成合并。

解决方案

前置处理:清理数据

数据中存在< LOD字符值,需先转换为NA并将数值列转为数值类型,否则会导致绘图失败:

library(dplyr)
filtered_el <- filtered_el %>%
  mutate(across(c(Ca, P, Si, Mg, Sr, Fe, K, Al), ~as.numeric(ifelse(. == "< LOD", NA, .))))

方案一:循环生成图存列表,用ggarrange合并

使用ggpubr包的ggarrange函数,先通过循环将每个子图存入列表,再一次性合并:

library(ggplot2)
library(ggpubr)

# 定义变量列表
variables <- c('Ca', 'P', 'Si', 'Mg', 'Sr', 'Fe', 'K', 'Al')
# 创建空列表存储子图
plot_list <- list()

# 循环生成每个变量的散点图
for (var in variables) {
  p <- ggplot(filtered_el, aes(x = Sample, y = .data[[var]], color = Site)) +
    geom_point(size = 2, show.legend = FALSE) +
    ylab(var) +
    theme_bw()
  plot_list[[var]] <- p
}

# 合并所有子图,设置为2行4列布局
combined_plot <- ggarrange(plotlist = plot_list, nrow = 2, ncol = 4)
print(combined_plot)

说明:

  • 用.data[[var]]是ggplot2推荐的动态引用变量的方式,比直接取列更规范。
  • 可通过ggarrange的nrow和ncol参数调整布局,比如4行2列。

方案二:宽转长数据+分面绘制(更简洁)

利用tidyr将宽格式数据转为长格式,再用facet_wrap一次性生成所有子图,无需循环:

library(ggplot2)
library(tidyr)
library(dplyr)

# 宽格式转长格式
filtered_el_long <- filtered_el %>%
  pivot_longer(cols = all_of(variables), 
               names_to = "Variable", 
               values_to = "Value")

# 绘制分面散点图
combined_plot <- ggplot(filtered_el_long, aes(x = Sample, y = Value, color = Site)) +
  geom_point(size = 2, show.legend = FALSE) +
  facet_wrap(~Variable, nrow = 2, ncol = 4, scales = "free_y") + # y轴自由缩放适配不同变量范围
  theme_bw()

print(combined_plot)

说明:

  • scales = "free_y"参数让每个子图的y轴根据自身数据范围调整,避免因变量数值差异过大导致部分图显示异常。
  • 这种方法更符合tidyverse的数据分析流程,代码更简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 21:20:26