rcolorsnodesggraph

How to control node color in ggraph?


I have a network graph, and I would like to color the edges to match their respective nodes. This is rather straight forward in an igraph plot, but I'd prefer to do in ggraph as I like the other aesthetics offered by the package.

There seems to be little control over node color within the ggraph; while edge color is covered extensively.

My question is this: how can I match my edges to their nodes that have been colored using a custom function, so that each edge that 'leaves' a node is colored the same as its node. This should help people follow flows through the network easier. A more generally question is this: how does ggraph assign colors outside of the aesthetic argument. My question is similar to another question I've asked here before, but the other way around (match edges to nodes), found here.

Here is a reproducible example:

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


Solution

  • I personally find working explicitly with the layout object helpful to understand the variable mapping.

    It has the classes "layout_igraph"+"layout_ggraph"+"data.frame" and contains

    1. a data.frame for the nodes with their coordinates as defined by create_layout as well as
    2. the input "tbl_graph"+"igraph" object (see attributes(layout)$graph)

    The former is accessed by geom_node_point to draw the nodes, the latter by geom_edge_fan to draw the edges.

    The color of the nodes can be controlled with the ggplot2 standard scale_color_manual, the color of the edges with the ggraph addition scale_edge_color_manual. Both can be used with the same node-name~color mapping if the limits attribute is set accordingly, because it contains...

    a character vector that defines possible values of the scale and their order.


    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