I have a network of nodes and edges which I would like to visualize as a linear arcplot. Based on my limited knowledge, I believe that {ggraph}
is a good tool for this (especially given my familiarity with {ggplot2}
) so that's what I'm trying here, but if theres's a compelling alternative I'm open to it.
I know it can render arcs above the line of nodes (as shown in my example below) but can also sometimes render them below. It looks like this can be controled by the strength
argument. This works when I put strength
outside aes
for the arc (e.g. strength = -1
flips them all down), but gives the warning Ignoring unknown aesthetics: strength
when applied inside aes
as shown below.
Below is a simple example to illustrate what I've tried so far and the resulting plot. I have searched StackOverflow and the ggraph documentation but can't seem to find the answer there. I have also tried the variants geom_edge_arc2
and geom_edge_arc0
without success. As a workaround, I could make a vector of values to feed to strength
outside aes
, but ideally I could do something inside aes
with the data already provided to the function. Am I misunderstanding the intended syntax or being too picky?
I would like to be able to control the direction (above or below) of each arc. For example, blue arcs above and red below based on the sign of edge_width
(i.e. strength = sign(edge_width)
).
# load packages
library(tidyverse, warn.conflicts = FALSE)
library(tidygraph, warn.conflicts = FALSE)
library(igraph, warn.conflicts = FALSE)
library(ggraph, warn.conflicts = FALSE)
# make random sim data reproducible
set.seed(1)
# define nodes
nodes <- data.frame(node_name = paste0("node", 1:5))
# define edges
edges <- t(combn(nodes$node_name, 2)) %>%
as_tibble(.name_repair = "universal") %>%
rename(from = 1, to = 2) %>%
mutate(edge_width = sample(x = -10:10, size = nrow(.), replace = T))
#> New names:
#> * `` -> ...1
#> * `` -> ...2
# build network from nodes and edges
network <- tbl_graph(edges = edges, nodes = nodes, directed = FALSE)
# visualize network as arcplot
network %>%
ggraph(layout = "linear") +
geom_edge_arc(aes(color = edge_width >= 0,
width = abs(edge_width),
strength = sign(edge_width)),
alpha = 0.65) +
geom_node_label(aes(label = node_name), size = 3)
#> Warning: Ignoring unknown aesthetics: strength
Created on 2021-02-26 by the reprex package (v1.0.0)
In case it matters:
sessionInfo()
#> R version 4.0.3 (2020-10-10)
#> Platform: x86_64-w64-mingw32/x64 (64-bit)
#> Running under: Windows 10 x64 (build 18363)
#>
#> Matrix products: default
#>
#> locale:
#> [1] LC_COLLATE=English_United States.1252
#> [2] LC_CTYPE=English_United States.1252
#> [3] LC_MONETARY=English_United States.1252
#> [4] LC_NUMERIC=C
#> [5] LC_TIME=English_United States.1252
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> loaded via a namespace (and not attached):
#> [1] ps_1.5.0 digest_0.6.27 assertthat_0.2.1 magrittr_2.0.1
#> [5] reprex_1.0.0 evaluate_0.14 highr_0.8 stringi_1.5.3
#> [9] rlang_0.4.10 cli_2.3.1 rstudioapi_0.13 fs_1.5.0
#> [13] rmarkdown_2.7 tools_4.0.2 stringr_1.4.0 glue_1.4.2
#> [17] xfun_0.21 yaml_2.2.1 compiler_4.0.2 htmltools_0.5.1.1
#> [21] knitr_1.31
Created on 2021-02-26 by the reprex package (v1.0.0)
It's been almost a year so until a better answer arrives, I'll post my workaround as a solution in case anyone else has this issue.
As proposed in the question, a workaround is to separately pull a vector of strength
values and then feed that to the geom_edge_arc
call outside of aes
.
# load packages
library(tidyverse)
library(tidygraph)
library(igraph)
library(ggraph)
# make random sim data reproducible
set.seed(1)
# define nodes
nodes <- data.frame(node_name = paste0("node", 1:5))
# define edges
edges <- t(combn(nodes$node_name, 2)) %>%
as_tibble(.name_repair = "universal") %>%
rename(from = 1, to = 2) %>%
mutate(edge_width = sample(x = -10:10, size = nrow(.), replace = T))
# extract vector of desired arc positions based on sign of edge width
arc_direction <- sign(edges$edge_width)
# build network from nodes and edges
network <- tbl_graph(edges = edges, nodes = nodes, directed = FALSE)
# visualize network as arcplot
network %>%
ggraph(layout = "linear") +
geom_edge_arc(aes(color = edge_width >= 0,
width = abs(edge_width)),
strength = arc_direction,
alpha = 0.65) +
geom_node_label(aes(label = node_name), size = 3)
Created on 2021-12-30 by the reprex package (v2.0.1)