如何在Markdown PDF中生成可保留分类变量的双变量3D核密度图?
解决方案:生成可嵌入PDF的分组3D双变量核密度图
以下是基于MASS::kde2d和lattice::wireframe的实现方案,既能生成静态3D图支持PDF嵌入,又能实现分组对比:
步骤1:加载依赖包
library(MASS) # 计算双变量核密度 library(lattice) # 绘制静态3D图 library(dplyr) # 分组数据处理
步骤2:定义密度计算函数
编写函数处理单组数据,输出适配wireframe的网格密度数据:
compute_2dkde <- function(data) { # 计算双变量核密度,匹配原ggplot的坐标轴范围 kde_result <- kde2d( x = data$duration, y = data$deviation, n = 100, # 控制3D图分辨率,值越高越精细 lims = c( 0, quantile(data$duration, 0.9), quantile(data$deviation, 0.01), quantile(data$deviation, 0.99) ) ) # 转换为长格式data.frame,适配wireframe调用格式 kde_df <- expand.grid(x = kde_result$x, y = kde_result$y) kde_df$z <- as.vector(kde_result$z) return(kde_df) }
步骤3:分组计算密度数据
假设你的分组非数值变量为group_var,用dplyr批量处理每组数据:
grouped_kde_data <- final %>% group_by(group_var) %>% do(compute_2dkde(.)) %>% ungroup()
步骤4:绘制分组3D密度图
用wireframe生成静态3D图,支持按分组变量拆分展示:
wireframe( z ~ x * y | group_var, data = grouped_kde_data, xlab = list(label = "时长", rot = -30), ylab = list(label = "预约偏差", rot = 30), zlab = list(label = "密度", rot = 90), scales = list(arrows = FALSE, col = "black"), shade = TRUE, # 开启阴影增强立体感 aspect = c(1, 1), # 调整坐标轴比例 par.settings = list( axis.line = list(col = "transparent"), strip.background = list(col = "#f0f0f0") ) )
方案优势
- 静态矢量图:wireframe生成的图可直接嵌入R Markdown PDF输出,无需依赖交互式组件,解决rgl/plotly的嵌入问题
- 分组支持:通过
group_by+do处理分组数据,| group_var实现类似facet的拆分展示,完美替代facet_grid - 参数可控:可通过
kde2d的n调整分辨率,lims匹配原ggplot的坐标轴范围,保证数据一致性
内容的提问来源于stack exchange,提问作者Javier Lopez
相关产品推荐
相关产品推荐

