如何在ggraph中控制节点颜色?

时间:2019-01-14 16:31:21

标签: r colors nodes ggraph

我有一个网络图,我想为边缘着色以匹配它们各自的节点。在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()

enter image description here

2 个答案:

答案 0 :(得分:1)

我个人发现显式使用layout对象有助于理解变量映射。

它具有类“ layout_igraph” +“ layout_ggraph” +“ data.frame”,并且包含

  1. data.frame用于节点,其坐标由create_layout
  2. 定义
  3. 输入的“ tbl_graph” +“ igraph”对象(请参见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()

example graph

答案 1 :(得分:0)

此后,我学会了如何执行此操作。它实际上非常简单,并利用了tidygraph的优势,我建议将其用于图形分析。它与ggraph配对使用,因此可以实现良好的工作流程。

基本上,您希望将nodeedge列上的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)

enter image description here