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

如何在R中将多个带置信区间的ggplot2二维轨迹图堆叠为3D图?

问题描述

我现有一段ggplot2代码,可绘制包含3条轨迹(对应variable列的3个唯一值)及置信区间的二维图,代码如下:

ggplot(df, aes(x=time, y=value, group=variable, color=variable, stroke=1.5))+ 
  
  geom_rect(aes(xmin = -Inf,xmax = 7,ymin = -Inf, ymax = Inf),
            fill="#DAEAF1", 
            alpha = .2)+
  geom_vline(xintercept=7)+
  stat_summary(geom="ribbon", fun.data=mean_cl_normal, width=0.1, conf.int=0.95)+
  stat_summary(geom="line", fun.y=mean, linetype="dashed")+
  stat_summary(geom="point", fun.y=mean, shape=8, size=1)

数据框df的表头及示例数据如下:

X time    variable     value
1 1 0.00 M 0.1507799
2 2 0.33 M 0.1254237
3 3 1.00 M 0.3680203
4 4 3.00 M 0.6286472
5 5 7.00 M 0.7751938
6 6 7.33 M 0.7857143

现有多个类似的数据框df1、df2、df3,希望将各自对应的ggplot2图堆叠成堆叠式3D效果,询问在R中的实现方法。

解决方案

这里提供两种可行的实现方式:

方法一:用patchwork制作伪3D堆叠图

这种方式保留ggplot2的绘图风格,通过调整图的位置、偏移和透明度模拟3D堆叠效果,适合需要保持原图表细节的场景。

步骤及代码:

  1. 给每个数据框添加分组标识,定义统一的绘图函数,调整Y轴偏移和透明度来体现层级深度;
  2. 用阴影层增强3D立体感,最后组合所有图层。
library(ggplot2)
library(patchwork)

# 给各数据框添加分组标识
df1$group <- "Group 1"
df2$group <- "Group 2"
df3$group <- "Group 3"

# 定义统一绘图函数,支持Y轴偏移和透明度调整
plot_func <- function(data, y_offset = 0, alpha_val = 1, fill_alpha = 0.2) {
  ggplot(data, aes(x=time, y=value + y_offset, group=variable, color=variable))+ 
    geom_rect(aes(xmin = -Inf,xmax = 7,ymin = -Inf, ymax = Inf),
              fill="#DAEAF1", 
              alpha = fill_alpha)+
    geom_vline(xintercept=7, alpha = alpha_val)+
    stat_summary(geom="ribbon", fun.data=mean_cl_normal, width=0.1, conf.int=0.95, alpha=0.3*alpha_val)+
    stat_summary(geom="line", fun.y=mean, linetype="dashed", alpha=alpha_val)+
    stat_summary(geom="point", fun.y=mean, shape=8, size=1, alpha=alpha_val)+
    theme_minimal()+
    theme(axis.title.y = element_blank(),
          axis.text.y = element_blank(),
          axis.ticks.y = element_blank(),
          panel.grid = element_blank())
}

# 绘制三个层级的图,设置不同偏移和透明度
p1 <- plot_func(df1, y_offset = 0, alpha_val = 1, fill_alpha = 0.2)
p2 <- plot_func(df2, y_offset = 0.5, alpha_val = 0.7, fill_alpha = 0.15)
p3 <- plot_func(df3, y_offset = 1.0, alpha_val = 0.5, fill_alpha = 0.1)

# 制作阴影层增强深度感
shadow <- ggplot() + 
  geom_rect(aes(xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf), fill="black", alpha=0.1) +
  theme_void()

# 组合图形并添加分组标签
(p3 + inset_element(shadow, left=0.02, bottom=0.02, right=0.98, top=0.98)) +
  inset_element(p2, left=0.01, bottom=0.01, right=0.99, top=0.99) +
  inset_element(p1, left=0, bottom=0, right=1, top=1) +
  plot_layout(ncol=1) +
  annotate("text", x=7, y=0, label="Group 1", hjust=1, vjust=0) +
  annotate("text", x=7, y=0.5, label="Group 2", hjust=1, vjust=0) +
  annotate("text", x=7, y=1.0, label="Group 3", hjust=1, vjust=0)

方法二:用plot3D绘制真正的3D轨迹图

如果需要更严谨的3D呈现或交互效果,可以使用plot3D包,将每个数据框对应Z轴的一个层级,直接绘制3D空间中的轨迹。

步骤及代码:

  1. 合并所有数据框并添加Z轴坐标区分层级;
  2. 计算每个层级的均值和置信区间,绘制3D轨迹、点及置信区间线。
library(plot3D)
library(dplyr)

# 合并数据框并添加Z轴坐标(对应不同数据框)
combined_df <- bind_rows(
  df1 %>% mutate(z = 1),
  df2 %>% mutate(z = 2),
  df3 %>% mutate(z = 3)
)

# 计算每个(time, variable, z)组合的均值和95%置信区间
summary_df <- combined_df %>%
  group_by(time, variable, z) %>%
  summarise(mean_val = mean(value),
            ci_low = mean_cl_normal(value)$ymin,
            ci_high = mean_cl_normal(value)$ymax) %>%
  ungroup()

# 绘制基础3D散点图
par(mar = c(2, 2, 2, 2))
scatter3D(summary_df$time, summary_df$z, summary_df$mean_val,
          col = as.numeric(factor(summary_df$variable)),
          pch = 8, cex = 1,
          xlab = "Time", ylab = "Group", zlab = "Value",
          ticktype = "detailed",
          bty = "g")

# 添加轨迹线
for (v in unique(summary_df$variable)) {
  sub_df <- filter(summary_df, variable == v)
  lines3D(sub_df$time, sub_df$z, sub_df$mean_val,
          col = as.numeric(factor(v)), lty = 2, add = TRUE)
}

# 添加置信区间(用上下两条虚线模拟)
for (v in unique(summary_df$variable)) {
  sub_df <- filter(summary_df, variable == v)
  lines3D(sub_df$time, sub_df$z, sub_df$ci_low,
          col = as.numeric(factor(v)), lty = 3, add = TRUE)
  lines3D(sub_df$time, sub_df$z, sub_df$ci_high,
          col = as.numeric(factor(v)), lty = 3, add = TRUE)
}

# 添加分组标签
text3D(x = max(summary_df$time), y = c(1,2,3), z = max(summary_df$mean_val),
       labels = c("Group 1", "Group 2", "Group 3"),
       col = 1, add = TRUE)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 07:50:25