rigraphgraph-visualizationvisnetworkggnetwork

Why this Network plot doesn't keep the nodes from same group together in R?


I have dataframe nodes with the group information like below:

dput(nodes)

structure(list(id = c("AC006329.1", "AC027796.4", "AC111170.2", 
"AC111170.3", "AC138207.4", "AP000695.2", "CDK15", "COL14A1", 
"COL15A1", "DDX11-AS1", "FOXP4-AS1", "IFNG-AS1", "ITGB2-AS1", 
"LINC00944", "LINC01213", "LINC01395", "MIR155HG", "MSTRG.108144", 
"MSTRG.110466", "MSTRG.11483", "MSTRG.130624", "MSTRG.134576", 
"MSTRG.147129", "MSTRG.180740", "MSTRG.180762", "MSTRG.24184", 
"MSTRG.9061", "SERHL"), label = c("AC006329.1", "AC027796.4", 
"AC111170.2", "AC111170.3", "AC138207.4", "AP000695.2", "CDK15", 
"COL14A1", "COL15A1", "DDX11-AS1", "FOXP4-AS1", "IFNG-AS1", "ITGB2-AS1", 
"LINC00944", "LINC01213", "LINC01395", "MIR155HG", "MSTRG.108144", 
"MSTRG.110466", "MSTRG.11483", "MSTRG.130624", "MSTRG.134576", 
"MSTRG.147129", "MSTRG.180740", "MSTRG.180762", "MSTRG.24184", 
"MSTRG.9061", "SERHL"), group = structure(c(1L, 6L, 6L, 6L, 4L, 
3L, 4L, 4L, 4L, 1L, 1L, 2L, 2L, 2L, 5L, 5L, 2L, 4L, 2L, 1L, 6L, 
5L, 5L, 3L, 3L, 3L, 1L, 5L), levels = c("blue", "brown", "cyan", 
"green", "purple", "red"), class = "factor")), row.names = c(NA, 
-28L), class = "data.frame") 

And the edges look like below:

here is the edges.csv file

Using nodes and edges I used the below code to create the network plot:

When I used like below, the network plot was constantly moving and doesn't stop at all.

visNetwork(nodes, edges)

I also tried adding visPhysics(stabilization = FALSE) to above line, but didn't work.

So, I tried like below with igraph layout:

visNetwork(nodes, edges) %>%
  visIgraphLayout()

enter image description here

This doesn't keep the nodes from same group together. Can anyone please tell me how to keep the nodes from same group / color together?

It should look like below:

enter image description here


Solution

  • I usually find it easier to customize a network graph using the tidygraph and ggraph ecosystem. Your graph has a lot more edges than the given example, so it might take some tweaks to get the edges looking as you want them.

    library(tidygraph)
    library(ggraph)
    
    # Match colours in given example:
    colormap <- c(red = '#fa3233', blue = '#3d85e9',
      green = '#4cb30f', purple = '#7b29ef',
      cyan = '#e02aef', brown = '#ffa500')
    
    fillmap <- c(red = '#fb7e81', blue = '#97c2fc',
                 green = '#7be142', purple = '#ad85e4',
                 cyan = '#ea7cf3', brown = '#ffff00')
    
    tbl_graph(nodes, 
              cbind(edges, colour = nodes$group[match(edges$from, nodes$id)])) %>%
      ggraph(layout = 'igraph', algorithm = 'fr') +
      geom_edge_diagonal(aes(color = colour, width = weight)) +
      geom_node_circle(aes(r = 1, color = group, fill = group)) +
      coord_equal() +
      scale_edge_color_manual(values = colormap) +
      scale_color_manual(values = colormap) +
      scale_fill_manual(values = fillmap) +
      scale_edge_width_continuous(range = c(0.1, 5)) +
      theme_void() +
      theme(legend.position = 'none')
    

    enter image description here


    Edit

    To adjust the layout so that the groups are not too close together, and to label the nodes in a legible way, you could do:

    tbl_graph(nodes, 
              cbind(edges, colour = nodes$group[match(edges$from, nodes$id)])) %>%
      ggraph(layout = 'igraph', algorithm = 'fr', weights = (edges$weight)^0.2) +
      geom_edge_diagonal(aes(color = colour, width = weight)) +
      geom_node_label(aes(label = label, fill = group, color = group), size = 3,
                      label.r = unit(0.5, "lines")) +
      geom_node_text(aes(label = label), size = 3) +
      coord_equal(clip = 'off') +
      scale_edge_color_manual(values = colormap) +
      scale_color_manual(values = colormap) +
      scale_fill_manual(values = fillmap) +
      scale_edge_width_continuous(range = c(0.1, 5)) +
      theme_void() +
      theme(legend.position = 'none')
    

    enter image description here