R语言Plotly绘制Sunburst图时最外层未显示全部值
解决Plotly Sunburst图仅显示部分外层数据的问题
我使用细胞空间切片数据绘制Sunburst图,原始数据结构如下:
structure(list(slide = c("LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095" ), stroma_bins = structure(c(1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L), levels = c("0-10% Stroma", "10-20% Stroma", "20-30% Stroma", "30-40% Stroma", "40-50% Stroma", "50-60% Stroma", "60-70% Stroma", "70-80% Stroma", "80-90% Stroma", "90-100% Stroma"), class = "factor"), cd8_percent_bins = structure(c(1L, 1L, 3L, 1L, 2L, 1L, 2L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L), levels = c("0-2% CD8+ Cells", "2-4% CD8+ Cells", "4-6% CD8+ Cells", "6-8% CD8+ Cells", "8-10% CD8+ Cells", "10-15% CD8+ Cells", "15-20% CD8+ Cells", ">20% CD8+ Cells"), class = "factor"), Freq = c(8L, 5L, 1L, 7L, 1L, 7L, 2L, 15L, 4L, 4L, 2L, 15L, 4L, 3L, 2L, 12L, 15L, 1L, 4L, 2L, 1L, 1L, 16L, 12L, 8L, 8L, 4L, 1L, 3L, 1L, 14L, 4L, 17L, 6L, 9L, 11L, 5L, 2L, 51L, 18L, 24L, 24L, 17L, 32L, 21L, 11L)), row.names = c(NA, -46L), class = c("data.table", "data.frame"))
使用Plotly绘制Sunburst图时,仅显示了某一区域的最外层数据,当前代码如下:
fig <- plot_ly( labels = df2$labels, parents = df2$parents, values = df2$values, type = 'sunburst', branchvalues = 'total') fig
问题原因
出现这个问题的核心是层级数据结构不完整:Plotly的Sunburst需要完整的节点层级链(根节点 → 中间层节点 → 叶子节点),如果缺少中间层或根节点的定义,Plotly无法正确解析整个层级关系,导致部分节点无法渲染。
解决方案
需要先构建包含完整层级的数据集,具体步骤如下:
- 提取所有层级节点:根节点(slide值)、中间层(stroma_bins的所有类别)、叶子节点(cd8_percent_bins的所有类别)
- 分别定义每个节点的父节点:根节点的父节点为空字符串,中间层节点的父节点是根节点,叶子节点的父节点对应的stroma_bins类别
- 计算每个节点的values:根节点是所有Freq的总和,中间层节点是对应stroma_bins下的Freq总和,叶子节点是原始数据的Freq值
完整代码示例:
library(plotly) library(data.table) # 加载原始数据 df <- structure(list(slide = c("LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095", "LU095" ), stroma_bins = structure(c(1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L), levels = c("0-10% Stroma", "10-20% Stroma", "20-30% Stroma", "30-40% Stroma", "40-50% Stroma", "50-60% Stroma", "60-70% Stroma", "70-80% Stroma", "80-90% Stroma", "90-100% Stroma"), class = "factor"), cd8_percent_bins = structure(c(1L, 1L, 3L, 1L, 2L, 1L, 2L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L), levels = c("0-2% CD8+ Cells", "2-4% CD8+ Cells", "4-6% CD8+ Cells", "6-8% CD8+ Cells", "8-10% CD8+ Cells", "10-15% CD8+ Cells", "15-20% CD8+ Cells", ">20% CD8+ Cells"), class = "factor"), Freq = c(8L, 5L, 1L, 7L, 1L, 7L, 2L, 15L, 4L, 4L, 2L, 15L, 4L, 3L, 2L, 12L, 15L, 1L, 4L, 2L, 1L, 1L, 16L, 12L, 8L, 8L, 4L, 1L, 3L, 1L, 14L, 4L, 17L, 6L, 9L, 11L, 5L, 2L, 51L, 18L, 24L, 24L, 17L, 32L, 21L, 11L)), row.names = c(NA, -46L), class = c("data.table", "data.frame")) # 1. 构建根节点数据 root <- data.table( labels = unique(df$slide), parents = "", values = sum(df$Freq) ) # 2. 构建中间层(stroma_bins)数据 stroma_level <- df[, .(values = sum(Freq)), by = stroma_bins] setnames(stroma_level, "stroma_bins", "labels") stroma_level[, parents := unique(df$slide)] # 3. 构建叶子节点(cd8_percent_bins)数据 leaf_level <- df[, .(labels = cd8_percent_bins, parents = stroma_bins, values = Freq)] # 4. 合并所有层级数据 df2 <- rbind(root, stroma_level, leaf_level) # 绘制Sunburst图 fig <- plot_ly( data = df2, labels = ~labels, parents = ~parents, values = ~values, type = 'sunburst', branchvalues = 'total' ) fig
代码说明
- 根节点:以切片名称"LU095"作为顶层,值为所有样本的频数总和
- 中间层:每个stroma比例区间作为节点,父节点是根节点,值为对应区间的频数总和
- 叶子节点:每个CD8+细胞比例区间作为节点,父节点是对应的stroma区间,值为原始数据中的频数
branchvalues = 'total'表示子节点的values总和等于父节点的value,符合层级求和逻辑
这样就能完整渲染出包含所有层级的Sunburst图,不会出现部分节点缺失的情况。
内容的提问来源于stack exchange,提问作者fgootkind
相关产品推荐
相关产品推荐

