I am trying to generate an interaction network plot with labeled nodes in a circular layout. I have cobbled together a functional script that shows the connections I want with ggraph, but I can't figure out how to position the node labels relative to the location in the circular arrangement, so they don't overlap with the connecting lines at any location. Someone has posted a very nice solution for the same problem when using igraph (Placing vertex.label outside a circular layout in igraph); but I don't think this will work with ggraph because the way the location of the nodes is calculated seems to be different. I'd prefer to use ggraph for this, because it has a built-in legend function that makes my life easier. This is what I have so far:
library(igraph)
library(tidyverse)
library(ggraph)
# Create example matrix
id <- c("s01", "s02", "s03", "s04", "s05")
s01 <- c(0, 0, 0, 1, 1)
s02 <- c(0, 0, 1, 1, 1)
s03 <- c(1, 0, 0, 0, 1)
s04 <- c(0, 1, 0, 0, 0)
s05 <- c(0, 0, 0, 0, 0)
links <- data.frame(id, s01, s02, s03, s04, s05)
links <- column_to_rownames(links, var = "id")
links <- as.matrix(links)
expertise <- c("neuro", "micro", "phys", "phys", "neuro")
nodes <- data.frame(id, expertise)
# Generate igraph object
network <- graph_from_adjacency_matrix(links, weighted = NULL, mode = "undirected")
# Generate plot
ggraph(network, layout = "circle") + geom_edge_arc(color = "darkgray", strength = 0.15) +
geom_node_point(size = 8, aes(color = nodes$expertise)) + geom_node_text(aes(label = id), nudge_y = -0.2) +
theme_void()
This generates the following plot:
The problem is that labels like s02 are inside the network, which becomes an issue with denser plots.
Is there a way to place all labels outside the circle of nodes? Any help would be most appreciated!
This is not wholly satisfactory as it requires assigning the plot as an intermediate step because the geom nudge
arguments don't take a function but you can nudge the labels outwards relative to the node xy coordinates:
library(igraph)
library(ggplot2)
library(ggraph)
# Generate igraph object
network <- graph_from_adjacency_matrix(links, weighted = NULL, mode = "undirected")
# Generate plot
p <- ggraph(network, layout = "circle") +
geom_edge_arc(color = "darkgray", strength = 0.15) +
geom_node_point(size = 8, aes(color = nodes$expertise)) +
theme_void()
p +
geom_node_text(aes(label = id), nudge_x = p$data$x * .1, nudge_y = p$data$y * .1)