Search code examples
rggplot2tidyverseggraph

linear graph with specific scale for nodes in ggraph R


I'm experimenting with the outstanding ggraph library to depict some really-hard to depict interrelationships for a scientific work. Specifically, I want to show SNP-SNP interactions in a genetic locus. It would be very nice if I plotted the interactions as curved nodes of a graph, where the SNPs are positioned in a linear fashion according to their genetic positions. The geom_edge_arc() aesthetics from the ggraph library would be ideal. However, I cannot put the nodes in an order according to the positions.

Here is an example

library(igraph)
library(tidyverse)
library(ggraph)

set.seed(10)
nodes <- tibble(nodes = paste("SNP",seq(1:10)), pos = sample(c(10000:20000),10))
edges <- expand.grid(nodes$nodes,nodes$nodes) %>% 
              mutate(interaction = rnorm(100)) %>%
              filter(abs(interaction)>1)

gr <- graph_from_data_frame(edges, vertices = nodes)

ggraph(gr, 'linear', circular=F) +
  geom_edge_arc(aes(edge_width=interaction)) 

The nodes are evenly spaced here, as "factors". However, I wanted to place them on the x coordinate as specified by the pos variable (which in turn becomes an attribute of the nodes). Adding + geom_node_point(aes(x=pos))to the ggplot object doesn't result in a correct rendering. I could probably do the plot with "basic" ipgraph too, but I like ggraph and ggplot2, and it would be an elegant and easy way to plot with this.

Kind regards, and thanks in advance,

Robert


Solution

  • Not sure if this is still relevant, but there are two ways to solve this.

    As noted by @axeman, you can use the manual layout, and basically pass the x and y coordinates to it:

    ggraph(gr, 
           layout = 'manual', 
           node.position = data_frame(y = rep(0, length(nodes$pos)), x = nodes$pos)) +
      geom_edge_arc(aes(edge_width=interaction))
    

    The othe way is to overrride the x aes inside geom_edge_arc. To be able to pass a node attribute to an aes we need to use geom_edge_arc2:

    ggraph(gr, 'linear', circular=F) +
      geom_edge_arc2(aes(edge_width=interaction, x = node.pos))
    

    Created on 2018-05-30 by the reprex package (v0.2.0).