如何用grid.arrange排列shapviz的sv_dependence图:统一尺寸且仅显示一次色条
问题描述
尝试使用grid.arrange()将shapviz包中的三个sv_importance()绘图排列在一行,仅在第三个图显示特征值颜色刻度(色条),但当前第三个图因色条占据额外宽度,导致三个图的主体绘图区域尺寸不一致。需要让三个图的主体区域尺寸相同,同时保留第三个图的色条。
可复现代码:
library(shapviz) library(ggplot2) library(gridExtra) set.seed(1) X_train <- data.matrix(`colnames<-`(replicate(26, rnorm(100)), LETTERS)) dtrain <- xgboost::xgb.DMatrix(X_train, label = rnorm(100)) fit <- xgboost::xgb.train(data = dtrain, nrounds = 50) shp <- shapviz(fit, X_pred = X_train) p_a <- sv_importance(shp, kind = "beeswarm", show_numbers = TRUE, max_display = 15, color_bar_title=NULL) p_b <- sv_importance(shp, kind = "beeswarm", show_numbers = TRUE, max_display = 15, color_bar_title=NULL) p_c <- sv_importance(shp, kind = "beeswarm", show_numbers = TRUE, max_display = 15) grid.arrange(p_a,p_b,p_c,nrow=1)
解决方案
方法1:使用patchwork包(推荐)
patchwork对ggplot对象的布局控制更灵活,能自动对齐绘图区域,同时可以统一管理图例显示。
代码示例:
library(shapviz) library(ggplot2) library(patchwork) set.seed(1) X_train <- data.matrix(`colnames<-`(replicate(26, rnorm(100)), LETTERS)) dtrain <- xgboost::xgb.DMatrix(X_train, label = rnorm(100)) fit <- xgboost::xgb.train(data = dtrain, nrounds = 50) shp <- shapviz(fit, X_pred = X_train) p_a <- sv_importance(shp, kind = "beeswarm", show_numbers = TRUE, max_display = 15, color_bar_title=NULL) p_b <- sv_importance(shp, kind = "beeswarm", show_numbers = TRUE, max_display = 15, color_bar_title=NULL) p_c <- sv_importance(shp, kind = "beeswarm", show_numbers = TRUE, max_display = 15) # 排列并对齐绘图区域,仅保留一个色条 p_a + p_b + p_c + plot_layout(nrow = 1, guides = "collect") + theme(legend.position = "right")
方法2:使用gridExtra结合gtable调整宽度
如果坚持使用gridExtra,可以通过gtable对象手动调整前两个图的宽度,让它们预留出色条空间,与第三个图对齐。
代码示例:
library(shapviz) library(ggplot2) library(gridExtra) library(gtable) set.seed(1) X_train <- data.matrix(`colnames<-`(replicate(26, rnorm(100)), LETTERS)) dtrain <- xgboost::xgb.DMatrix(X_train, label = rnorm(100)) fit <- xgboost::xgb.train(data = dtrain, nrounds = 50) shp <- shapviz(fit, X_pred = X_train) p_a <- sv_importance(shp, kind = "beeswarm", show_numbers = TRUE, max_display = 15, color_bar_title=NULL) p_b <- sv_importance(shp, kind = "beeswarm", show_numbers = TRUE, max_display = 15, color_bar_title=NULL) p_c <- sv_importance(shp, kind = "beeswarm", show_numbers = TRUE, max_display = 15) # 转换为gtable对象 gt_a <- ggplotGrob(p_a) gt_b <- ggplotGrob(p_b) gt_c <- ggplotGrob(p_c) # 让前两个图的宽度与第三个图(含色条)一致 gt_a$widths <- gt_c$widths gt_b$widths <- gt_c$widths # 排列调整后的图形 grid.arrange(gt_a, gt_b, gt_c, nrow = 1)
内容的提问来源于stack exchange,提问作者kris
相关产品推荐
相关产品推荐

