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

如何用ggplot2将时间序列多变量箱线图整合到同一画布?

问题描述

我有一个名为validation.xlsx的Excel文件,包含132行时间序列数据,涉及time、observed(观测流量)、simulated(模拟流量)三个变量。目前已成功生成两个变量的单独箱线图,但无法将二者整合到同一画布中,寻求解决方案。

数据样例(前6行)

原始数据(df)

timeobservedsimulated
2011-01-01 00:00:0040.324.8
2011-02-01 00:00:0017.619.8
2011-03-01 00:00:0063.917.2
2011-04-01 00:00:00114.075.5
2011-05-01 00:00:00266.0269.0
2011-06-01 00:00:00120.087.2

季节分类后数据(seasons)

timeobservedsimulatedseasonTime1MonthYearSeason
2011-01-0140.324.8Winter2011-01-01012011Winter
2011-02-0117.619.8Winter2011-02-01022011Winter
2011-03-0163.917.2Winter2011-03-01032011Spring
2011-04-01114.075.5Winter2011-04-01042011Spring
2011-05-01266.0269.0Winter2011-05-01052011Spring
2011-06-01120.087.2Winter2011-06-01062011Summer

解决方案

提供两种常用整合方式,根据需求选择:

方式1:合并为同一坐标轴的分组箱线图(直接对比分布)

将宽格式数据转为长格式,用一个变量区分观测/模拟数据,实现同图分组展示:

# 加载依赖包
library(ggplot2)
library(tidyverse)
library(readxl)

# 读取并预处理数据
df <- read_excel("validation.xlsx")
df$time <- as.Date(df$time)

# 生成月份和季节列(修复原代码中Month生成逻辑)
seasons <- df %>%
  mutate(Month = format(time, "%m"),
         Season = case_when(
           Month %in% c("12", "01", "02") ~ "Winter",
           Month %in% c("03", "04", "05") ~ "Spring",
           Month %in% c("06", "07", "08") ~ "Summer",
           Month %in% c("09", "10", "11") ~ "Fall"
         ))

# 转换为长格式数据
long_seasons <- seasons %>%
  pivot_longer(
    cols = c(observed, simulated),
    names_to = "Data_Type",
    values_to = "Streamflow"
  )

# 绘制分组箱线图
combined_boxplot <- ggplot(long_seasons, aes(x = Month, y = Streamflow, fill = Data_Type)) +
  geom_boxplot(alpha = 0.5, position = position_dodge(width = 0.8)) + # 分组错开避免重叠
  labs(
    x = "月份",
    y = expression(paste("流量, ", m^3/s)),
    title = "月度流量箱线图 - 观测值vs模拟值",
    fill = "数据类型"
  ) +
  scale_fill_manual(values = c("observed" = "#1f77b4", "simulated" = "#ff7f0e")) + # 自定义对比色
  theme_minimal()

# 展示图形
print(combined_boxplot)

方式2:用patchwork拼接独立子图到同一画布

如果希望保留两个独立箱线图的结构,仅将它们放在同一画布展示,使用patchwork包实现拼接:

# 安装并加载patchwork(首次使用需安装)
# install.packages("patchwork")
library(patchwork)

# 保留原代码的两个独立箱线图
monthly_observed_boxplot <- ggplot(seasons, aes(x = Month)) +
  geom_boxplot(aes(y = observed, fill = Month), show.legend = F, alpha = 0.5) +
  labs(
    x = "月份",
    y = expression(paste("流量, ", m^3/s)),
    title = "月度箱线图 - 观测值"
  ) +
  theme_minimal()

monthly_simulated_boxplot <- ggplot(seasons, aes(x = Month)) +
  geom_boxplot(aes(y = simulated, fill = Month), show.legend = F, alpha = 0.5) +
  labs(
    x = "月份",
    y = expression(paste("流量, ", m^3/s)),
    title = "月度箱线图 - 模拟值"
  ) +
  theme_minimal()

# 拼接图形:+表示横向并排,/表示纵向上下排列
combined_plot <- monthly_observed_boxplot + monthly_simulated_boxplot +
  plot_annotation(
    title = "观测值与模拟值月度箱线图",
    theme = theme(plot.title = element_text(hjust = 0.5))
  )

# 展示图形
print(combined_plot)

关键提示

  • 原代码中seasons的Month列需确保是两位字符格式(如"01"而非"1"),否则季节分类会出错,建议用format(time, "%m")生成。
  • 方式1适合直接对比观测与模拟数据的分布差异;方式2适合保留两个图的独立性,便于分别查看细节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 02:20:55