如何在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堆叠效果,适合需要保持原图表细节的场景。
步骤及代码:
- 给每个数据框添加分组标识,定义统一的绘图函数,调整Y轴偏移和透明度来体现层级深度;
- 用阴影层增强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空间中的轨迹。
步骤及代码:
- 合并所有数据框并添加Z轴坐标区分层级;
- 计算每个层级的均值和置信区间,绘制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
相关产品推荐
相关产品推荐

