分享

树状数据/层次数据可视化

 阿越就是我 2023-10-12 发布于上海

💡专注R语言在🩺生物医学中的使用

树状结构的数据在生活中非常常见,比如层次聚类的结果,这种数据通常有一种包含关系,上面一层可以分为多个分支,每个分支又可以继续分。

这种数据的可视化方法非常多,今天介绍使用ggraph包可视化,功能很多,布局也很多,很多常见的网络图都是这个包画出来的。

加载R包

# libraries
library(ggraph)
## Loading required package: ggplot2
library(igraph)
## 
## Attaching package: 'igraph'
## The following objects are masked from 'package:stats':
## 
##     decompose, spectrum
## The following object is masked from 'package:base':
## 
##     union
suppressPackageStartupMessages(library(tidyverse))

数据结构

数据结构一般是2列,表示从哪里到哪里。

比如下面这个例子,最上面是根节点origin,然后下面有7个分支,分别是group1group5,每个group下面都有7个sub_group

d1 <- data.frame(from="origin", to=paste("group", seq(1,7), sep=""))
d2 <- data.frame(from=rep(d1$to, each=7), to=paste("subgroup", seq(1,49), sep="_"))
edges <- rbind(d1, d2)

edges
##      from          to
## 1  origin      group1
## 2  origin      group2
## 3  origin      group3
## 4  origin      group4
## 5  origin      group5
## 6  origin      group6
## 7  origin      group7
## 8  group1  subgroup_1
## 9  group1  subgroup_2
## 10 group1  subgroup_3
## 11 group1  subgroup_4
## 12 group1  subgroup_5
## 13 group1  subgroup_6
## 14 group1  subgroup_7
## 15 group2  subgroup_8
## 16 group2  subgroup_9
## 17 group2 subgroup_10
## 18 group2 subgroup_11
## 19 group2 subgroup_12
## 20 group2 subgroup_13
## 21 group2 subgroup_14
## 22 group3 subgroup_15
## 23 group3 subgroup_16
## 24 group3 subgroup_17
## 25 group3 subgroup_18
## 26 group3 subgroup_19
## 27 group3 subgroup_20
## 28 group3 subgroup_21
## 29 group4 subgroup_22
## 30 group4 subgroup_23
## 31 group4 subgroup_24
## 32 group4 subgroup_25
## 33 group4 subgroup_26
## 34 group4 subgroup_27
## 35 group4 subgroup_28
## 36 group5 subgroup_29
## 37 group5 subgroup_30
## 38 group5 subgroup_31
## 39 group5 subgroup_32
## 40 group5 subgroup_33
## 41 group5 subgroup_34
## 42 group5 subgroup_35
## 43 group6 subgroup_36
## 44 group6 subgroup_37
## 45 group6 subgroup_38
## 46 group6 subgroup_39
## 47 group6 subgroup_40
## 48 group6 subgroup_41
## 49 group6 subgroup_42
## 50 group7 subgroup_43
## 51 group7 subgroup_44
## 52 group7 subgroup_45
## 53 group7 subgroup_46
## 54 group7 subgroup_47
## 55 group7 subgroup_48
## 56 group7 subgroup_49

画图

首先转换数据为ggraph需要的格式。

mygraph <- graph_from_data_frame(edges)

ggraph(mygraph, layout = 'dendrogram', circular = FALSE) + 
  geom_edge_diagonal() +
  geom_node_point() +
  theme_void()
plot of chunk unnamed-chunk-3

一个简单的树状图就画好了。接下来进行一些美化操作,看看这个包的强大之处。

美化

通过组合不同的布局和线型,可以得到非常多神奇的结果。比如大家比较喜欢的圆形布局。

theme_set(theme_void())

p1 <- ggraph(mygraph, layout = 'dendrogram', circular = T) + 
  geom_edge_diagonal()+ 
  coord_fixed()

p2 <- ggraph(mygraph,layout = 'linear',circular=T) + 
  geom_edge_diagonal() +
  geom_node_point()+ 
  coord_fixed()

p3 <- ggraph(mygraph,layout = 'partition',circular=T) + 
  geom_node_arc_bar()+ 
  coord_fixed()

p4 <- ggraph(mygraph,layout = 'circlepack') + 
  geom_node_circle()+ 
  coord_fixed()

p5 <- ggraph(mygraph, 'circlepack') + 
  geom_edge_link() + 
  geom_node_point() +
  coord_fixed()
p6 <- ggraph(mygraph, 'treemap') + 
  geom_node_tile()

p7 <- ggraph(mygraph, 'tree') + 
  geom_edge_diagonal()

p8 <- ggraph(mygraph, 'unrooted') + 
  geom_edge_link()+ 
  coord_fixed()

p9 <- ggraph(mygraph, 'dendrogram', circular = TRUE) + 
  geom_edge_elbow() + 
  coord_fixed()

library(patchwork)

p1+p2+p3+p4+p5+p6+p7+p8+p9+plot_layout(ncol = 3)
plot of chunk unnamed-chunk-4

如果给数据增加一些属性列,就会变成大家在论文中常见的各种图形了!

就是这么简单!

给节点安排一些属性信息,把这些信息放在另一个数据框里。

name <- unique(c(as.character(edges$from), as.character(edges$to)))
vertices <- data.frame(
  name=name,
  group=c(rep(NA,8) ,  rep( paste("group", seq(1,7), sep=""), each=7)),
  cluster=sample(letters[1:4], length(name), replace=T),
  value=sample(seq(10,30), length(name), replace=T)
)

vertices
##           name  group cluster value
## 1       origin   <NA>       b    19
## 2       group1   <NA>       b    29
## 3       group2   <NA>       d    17
## 4       group3   <NA>       a    15
## 5       group4   <NA>       b    23
## 6       group5   <NA>       b    12
## 7       group6   <NA>       b    20
## 8       group7   <NA>       b    17
## 9   subgroup_1 group1       b    30
## 10  subgroup_2 group1       d    10
## 11  subgroup_3 group1       d    12
## 12  subgroup_4 group1       c    27
## 13  subgroup_5 group1       c    21
## 14  subgroup_6 group1       b    19
## 15  subgroup_7 group1       c    14
## 16  subgroup_8 group2       c    22
## 17  subgroup_9 group2       b    17
## 18 subgroup_10 group2       d    30
## 19 subgroup_11 group2       a    20
## 20 subgroup_12 group2       c    15
## 21 subgroup_13 group2       c    16
## 22 subgroup_14 group2       b    19
## 23 subgroup_15 group3       b    26
## 24 subgroup_16 group3       c    25
## 25 subgroup_17 group3       b    14
## 26 subgroup_18 group3       d    22
## 27 subgroup_19 group3       a    23
## 28 subgroup_20 group3       c    10
## 29 subgroup_21 group3       d    28
## 30 subgroup_22 group4       b    25
## 31 subgroup_23 group4       b    15
## 32 subgroup_24 group4       d    11
## 33 subgroup_25 group4       a    18
## 34 subgroup_26 group4       a    19
## 35 subgroup_27 group4       c    19
## 36 subgroup_28 group4       b    10
## 37 subgroup_29 group5       b    22
## 38 subgroup_30 group5       b    28
## 39 subgroup_31 group5       d    19
## 40 subgroup_32 group5       c    19
## 41 subgroup_33 group5       d    11
## 42 subgroup_34 group5       c    20
## 43 subgroup_35 group5       d    28
## 44 subgroup_36 group6       b    17
## 45 subgroup_37 group6       d    19
## 46 subgroup_38 group6       a    22
## 47 subgroup_39 group6       b    27
## 48 subgroup_40 group6       a    23
## 49 subgroup_41 group6       a    24
## 50 subgroup_42 group6       d    10
## 51 subgroup_43 group7       c    14
## 52 subgroup_44 group7       d    19
## 53 subgroup_45 group7       c    30
## 54 subgroup_46 group7       c    12
## 55 subgroup_47 group7       d    24
## 56 subgroup_48 group7       d    21
## 57 subgroup_49 group7       c    20

重新再画一下:

mygraph <- graph_from_data_frame(edges, vertices=vertices)
theme_set(theme_void())

p1 <- ggraph(mygraph, layout = 'dendrogram', circular = T) + 
  geom_edge_diagonal()+ 
  geom_node_point(aes(filter=leaf, size=value, color=group), alpha=0.6) +
  coord_fixed()

p2 <- ggraph(mygraph,layout = 'linear',circular=T) + 
  geom_edge_diagonal() +
  geom_node_point(aes(color=cluster,size=value))+ 
  coord_fixed()

p3 <- ggraph(mygraph,layout = 'partition',circular=T) + 
  geom_node_arc_bar(aes(fill=group))+ 
  coord_fixed()

p4 <- ggraph(mygraph,layout = 'circlepack') + 
  geom_node_circle(aes(fill=cluster))+ 
  coord_fixed()

p5 <- ggraph(mygraph, 'circlepack') + 
  geom_edge_link() + 
  geom_node_point(aes(colour = group,size=value)) +
  coord_fixed()

p6 <- ggraph(mygraph, 'treemap') + 
  geom_node_tile(aes(fill=value))

p7 <- ggraph(mygraph, 'dendrogram') + 
  geom_edge_diagonal()+
  geom_node_text(aes(label=name,filter=leaf,color=group), angle=90, hjust=1, nudge_y=-0.1) +
  geom_node_point(aes(filter=leaf, size=value, color=group), alpha=0.6)

p8 <- ggraph(mygraph, 'unrooted') + 
  geom_edge_link()+ 
  geom_node_point(aes(color=cluster,size=value))
  coord_fixed()

p9 <- ggraph(mygraph, 'dendrogram', circular = TRUE) + 
  geom_edge_elbow() + 
  geom_node_point(aes(color=cluster),size=4)
  coord_fixed()


library(patchwork)

p1+p2+p3+p4+p5+p6+p7+p8+p9+plot_layout(ncol = 3)
plot of chunk unnamed-chunk-7

简单,喜欢哪种就用哪种,但是要注意,我们提供的信息是点的,并不是线条的,所以如果你想让线条也有属性映射的话,需要在最开始构建from-to数据时添加线条属性哦~

如果你还不会,可以参考另一篇推文:R语言生信图表学习之网络图


医学和生信笔记,专注R语言在临床医学中的使用、R语言数据分析和可视化。主要分享R语言做医学统计学、meta分析、网络药理学、临床预测模型、机器学习、生物信息学等。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约