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()
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
data.frame
for the nodes with their coordinates as defined by create_layout
as well asattributes(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()