画图的内容,大家喜闻乐见,阅读量仅次于狗粮和故事。所以。。。我在没东西写的时候就写点画图的东西了,输出倒逼输入~
1.R包
library(tidyverse)
library(navdata)
library(networkD3)
2.示例数据集
data("phone.call2")
nodes <- phone.call2$nodes;head(nodes)
## # A tibble: 6 x 2
## id label
## <int> <chr>
## 1 1 France
## 2 2 Belgium
## 3 3 Germany
## 4 4 Danemark
## 5 5 Croatia
## 6 6 Slovenia
edges <- phone.call2$edges;head(edges)
## # A tibble: 6 x 3
## from to weight
## <int> <int> <dbl>
## 1 1 3 9
## 2 2 1 4
## 3 1 8 3
## 4 1 9 4
## 5 1 10 2
## 6 1 11 3
3.交互式网络图
使用networkD3 包里的forceNetwork函数。有一个比较严格的要求,就是节点必须要设置id,并且从0开始,不设置就报错,不堪吐槽哇。
nodes_d3 <- mutate(nodes, id = id - 1);head(nodes_d3)
## # A tibble: 6 x 2
## id label
## <dbl> <chr>
## 1 0 France
## 2 1 Belgium
## 3 2 Germany
## 4 3 Danemark
## 5 4 Croatia
## 6 5 Slovenia
edges_d3 <- mutate(edges, from = from - 1, to = to - 1);head(edges_d3)
## # A tibble: 6 x 3
## from to weight
## <dbl> <dbl> <dbl>
## 1 0 2 9
## 2 1 0 4
## 3 0 7 3
## 4 0 8 4
## 5 0 9 2
## 6 0 10 3
输入数据整対格式,出图就很简单
forceNetwork(
Links = edges_d3, Nodes = nodes_d3,
Source = "from", Target = "to", # so the network is directed.
NodeID = "label", Group = "id", Value = "weight",
opacity = 1, fontSize = 16, zoom = TRUE
)
4.桑基图
sankeyNetwork(
Links = edges_d3, Nodes = nodes_d3,
Source = "from", Target = "to",
NodeID = "label", Value = "weight",
fontSize = 16, unit = "Letter(s)")
可以给连线加上颜色
edges_d3$edgegroup = as.character(edges_d3$from)
sankeyNetwork(
Links = edges_d3, Nodes = nodes_d3,
Source = "from", Target = "to",
NodeID = "label", Value = "weight",
LinkGroup = "edgegroup",
fontSize = 16, unit = "Letter(s)")
5.换个数据试试看
mat = sample(0:5,27,replace = T)
mat = matrix(mat,nrow = 3)
rownames(mat) = paste0("S",1:nrow(mat))
colnames(mat) = paste0("T",1:ncol(mat))
mat
## T1 T2 T3 T4 T5 T6 T7 T8 T9
## S1 3 4 5 2 2 3 3 0 3
## S2 3 2 4 3 1 0 0 0 5
## S3 1 3 5 2 1 3 2 2 1
df <- gather(rownames_to_column(as.data.frame(mat),var = "from"),
key = "to",
value = "value",
- from);head(df)
## from to value
## 1 S1 T1 3
## 2 S2 T1 3
## 3 S3 T1 1
## 4 S1 T2 4
## 5 S2 T2 2
## 6 S3 T2 3
edges <- filter(df,value!=0)
x = unique(c(rownames(mat),colnames(mat)));length(x)
## [1] 12
y = 0:(sum(dim(mat))-1);length(y)
## [1] 12
for(i in 1:length(y)){
edges$from = str_replace(edges$from,
x[[i]],
as.character(y[[i]]))
edges$to = str_replace(edges$to,
x[[i]],
as.character(y[[i]]))
}
str(edges)
## 'data.frame': 23 obs. of 3 variables:
## $ from : chr "0" "1" "2" "0" ...
## $ to : chr "3" "3" "3" "4" ...
## $ value: int 3 3 1 4 2 3 5 4 5 2 ...
edges <- data.frame(apply(edges,2,as.numeric));head(edges)
## from to value
## 1 0 3 3
## 2 1 3 3
## 3 2 3 1
## 4 0 4 4
## 5 1 4 2
## 6 2 4 3
nodes <- data.frame(id = as.numeric(0:(sum(dim(mat))-1)),
label = c(rownames(mat),colnames(mat)));head(nodes)
## id label
## 1 0 S1
## 2 1 S2
## 3 2 S3
## 4 3 T1
## 5 4 T2
## 6 5 T3
照葫芦画瓢准备数据,对了就可以出图。
forceNetwork(
Links = edges, Nodes = nodes,
Source = "from", Target = "to", # so the network is directed.
NodeID = "label", Group = "id", Value = "value",
opacity = 1, fontSize = 16, zoom = TRUE
)
edges$edgegroup = as.character(edges$from)
sankeyNetwork(
Links = edges, Nodes = nodes,
Source = "from", Target = "to",
NodeID = "label", Value = "value",
LinkGroup = "edgegroup",
fontSize = 16, unit = "Letter(s)")