ggplotly转带凸包边框的PCA得分图时设置样本名tooltip后边框消失
问题背景
需要使用ggplot2绘制PCA得分图,再通过plotly包转换为交互式图表,要求为分组添加凸包形式的边框(不使用stat_ellipse生成的椭圆,已知椭圆方法可正常运行)。
故障现象
- 基础PCA点图绘制完成后,调用
ggplotly(p, tooltip = "label")设置悬停提示展示样本名,交互效果正常,样本名可正确显示 - 通过
chull()计算各分组凸包坐标,使用geom_polygon()添加半透明分组凸包边框时,静态ggplot图表渲染正常,边框可正确显示 - 对添加凸包的图表
p2调用ggplotly(p2, tooltip = "label")转换为交互图时,凸包边框直接消失
复现代码
library(ggplot2) library(plotly) library(dplyr) ## 构造演示数据 dat <- iris[1:4] Group <- iris$Species ## PCA计算 df_pca <- prcomp(dat, center = T, scale. = FALSE) df_pcs <- data.frame(df_pca$x, Group = Group) percentage <-round(df_pca$sdev^2 / sum(df_pca$sdev^2) * 100, 2) percentage <-paste(colnames(df_pcs),"(", paste(as.character(percentage), "%", ")", sep = "")) ## 基础点图绘制 Sample_Name <- rownames(df_pcs) p <- ggplot(df_pcs, aes(x = PC1, y = PC2, color = Group, label = Sample_Name)) + xlab(percentage[1]) + ylab(percentage[2]) + geom_point(size = 3) # 基础图转plotly正常 ggplotly(p, tooltip = "label")
## 添加凸包(故障版本) hull_group <- df_pcs %>% dplyr::mutate(Sample_Name = Sample_Name) %>% dplyr::group_by(Group) %>% dplyr::slice(chull(PC1, PC2)) p2 <- p + ggplot2::geom_polygon(data = hull_group, aes(fill = Group), alpha = 0.1) # 转plotly后凸包消失 ggplotly(p2, tooltip = "label")
故障原因
全局ggplot美学映射中设置了label = Sample_Name用于点图层的悬停提示,后续添加的geom_polygon凸包图层默认继承了该全局映射。ggplotly解析带label映射的填充多边形图层时存在逻辑冲突,会直接跳过该图层的渲染,最终导致凸包消失。
修复方法
在geom_polygon的美学映射中手动将label设为NULL,阻断凸包图层对全局label映射的继承即可,点图层的悬停提示功能不会受影响。
修复后的凸包添加代码如下:
## 添加凸包(修复版本) hull_group <- df_pcs %>% dplyr::mutate(Sample_Name = Sample_Name) %>% dplyr::group_by(Group) %>% dplyr::slice(chull(PC1, PC2)) p2 <- p + ggplot2::geom_polygon( data = hull_group, aes(fill = Group, label = NULL), alpha = 0.1 ) # 重新转换即可正常显示凸包,点的悬停样本名展示正常 ggplotly(p2, tooltip = "label")
补充说明:如果需要凸包区域悬停时展示分组信息,可以单独为多边形图层设置专属的映射字段,不要和点图层的label映射混用即可。
内容的提问来源于stack exchange,提问作者Wang
相关产品推荐
相关产品推荐

