我有一个网络图,我想为边缘着色以匹配它们各自的节点。在igraph
情节中,这很简单,但是我更喜欢在ggraph
中做,因为我喜欢包装提供的其他美学。
ggraph
中似乎几乎无法控制节点的颜色;同时边缘颜色被广泛覆盖。
我的问题是:我如何将边缘与使用自定义功能着色的节点匹配,以使“离开”节点的每个边缘的着色都与其节点相同。这应该可以帮助人们更轻松地跟踪通过网络的流量。一个更普遍的问题是:ggraph如何在美学论证之外分配颜色。我的问题与我之前在这里问过的另一个问题类似,但是相反(找到节点的边缘),发现here。
以下是可重现的示例:
library(tidyverse)
library(igraph)
library(ggraph)
library(tidygraph)
library(RColorBrewer)
## the custom function using Color Brewer
cols_f <- colorRampPalette(RColorBrewer::brewer.pal(11, 'Spectral'))
## make the graph
g <- erdos.renyi.game(50, .1)
# provide some names
V(g)$name <- 1:vcount(g)
#plot using ggraph
g %>%
as_tbl_graph() %>%
activate(nodes) %>%
mutate(degree = centrality_degree()) %>%
ggraph()+
geom_edge_fan(aes(color = as.factor(from),
alpha = ..index..),
show.legend = F)+
geom_node_point(aes(size = degree),
color = cols_f(vcount(g)), # custom function for node color
show.legend = F)+
scale_color_manual(values = cols_f(ecount(g)))+ # custom function for edge color
coord_equal()
答案 0 :(得分:1)
我个人发现显式使用layout
对象有助于理解变量映射。
它具有类“ layout_igraph” +“ layout_ggraph” +“ data.frame”,并且包含
data.frame
用于节点,其坐标由create_layout
和attributes(layout)$graph
) geom_node_point
访问前者以绘制节点,geom_edge_fan
访问后者以绘制边缘。
可以使用ggplot2标准scale_color_manual
控制节点的颜色,使用ggraph加法scale_edge_color_manual
控制边缘的颜色。如果limits
属性被相应地设置,则它们都可以使用相同的节点名〜颜色映射,因为它包含...
一个字符矢量,它定义小数位数及其顺序的可能值。
library(tidyverse)
library(igraph)
library(ggraph)
library(tidygraph)
## the custom function using Color Brewer
cols_f <- colorRampPalette(RColorBrewer::brewer.pal(11, 'Spectral'))
## make the graph
g <- erdos.renyi.game(50, .1)
# provide some names
V(g)$name <- 1:vcount(g)
# plot using ggraph
graph_tbl <- g %>%
as_tbl_graph() %>%
activate(nodes) %>%
mutate(degree = centrality_degree())
layout <- create_layout(graph_tbl, layout = 'igraph', algorithm = 'nicely')
ggraph(layout) +
geom_edge_fan(
aes(color = as.factor(from), alpha = ..index..),
show.legend = F
) +
geom_node_point(
aes(size = degree, color = as.factor(name)),
show.legend = F
) +
scale_color_manual(
limits = as.factor(layout$name),
values = cols_f(nrow(layout))
) +
scale_edge_color_manual(
limits = as.factor(layout$name),
values = cols_f(nrow(layout))
) +
coord_equal()
答案 1 :(得分:0)
此后,我学会了如何执行此操作。它实际上非常简单,并利用了tidygraph
的优势,我建议将其用于图形分析。它与ggraph
配对使用,因此可以实现良好的工作流程。
基本上,您希望将node
或edge
列上的from
数据与to
数据合并-取决于要与边缘匹配的节点
下面是一些执行此操作的代码。
# same as original code above
library(tidyverse)
library(igraph)
library(ggraph)
library(tidygraph)
library(RColorBrewer)
## the custom function using Color Brewer
cols_f <- colorRampPalette(RColorBrewer::brewer.pal(11, 'Spectral'))
## make the graph
g <- erdos.renyi.game(50, .1)
# provide some names
V(g)$name <- 1:vcount(g)
# Here's the new parts
#create random categories to the nodes
V(g)$category <- sample(LETTERS, vcount(g), T)
# turn igraph into tbl_graph (still igraph under the hood!)
g_tbl <- as_tbl_graph(g)
# create new tibble from nodes with a variable from to merge with edges
node_from <- g_tbl %>%
as_tibble() %>%
mutate(from = row_number())
# merge with edges on the new 'from' variable
new_g_tbl <- g_tbl %>%
activate(edges) %>%
left_join(node_from)
# plot
new_g_tbl %>%
ggraph() +
geom_edge_arc(
aes(color = category),
end_cap = circle(2.5, 'mm'),
arrow = arrow(length =
unit(2.5,
'mm'),
type = 'closed'),
strength = 0.1,
show.legend = F
) +
geom_node_point(aes(color = category),
show.legend = F)