1

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

beginner
  • 1,059
  • 8
  • 23
  • Where did you get the "desired outcome" image from? – Paul Stafford Allen Jul 24 '23 at 08:48
  • that is an example plot, I found online...here it is `https://www.r-bloggers.com/2019/06/interactive-network-visualization-with-r/` I showed this here just to say that I want my plot should look like this. – beginner Jul 24 '23 at 09:07
  • I think what you're looking for is a *force directed layout* (instead of the regular layout). The documentation of the package you're using probably has a section on graph layouts in which you'll find the desired function under keywords such as *force directed* or popular algorithms like "Fruchtermann-Reingold" or "Kamada-Kawai". See e.g. https://igraph.org/r/doc/layout_with_fr.html for igraph – I_O Jul 24 '23 at 09:38
  • Okay, but nothing changed with `layout_with_fr`. I used this way `visNetwork(data1, data5) %>% visIgraphLayout(layout = "layout_with_fr")` – beginner Jul 24 '23 at 11:36
  • You have a complete graph. Every vertex is connected to every other. Visualizing it this way is quite pointless ... All the information here is in the edge weights, so you might want to look for a way to indicate these. First, you need a graph layout which takes weights into account and makes high-weight edges short. `layout_with_fr` is like this. I don't know `visIgraphLayout` and what it needs to consider weights. – Szabolcs Jul 24 '23 at 20:45
  • Second, it makes sense to show the weights somehow. You can remove weak connections. Or show the weight through the edge thicknesses. – Szabolcs Jul 24 '23 at 20:46
  • If you could show me that with an example, it would be great. Thank you. – beginner Jul 25 '23 at 09:46

2 Answers2

3

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

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
3

This is what I have tried with igraph

g <- edges %>%
    mutate(
        color1 = with(nodes, as.character(group)[match(from, id)]),
        color2 = with(nodes, as.character(group)[match(to, id)])
    ) %>%
    mutate(color = ifelse(color1 == color2, color1, "gray")) %>%
    mutate(width = ifelse(color == "gray", weight, weight * 100)) %>%
    graph_from_data_frame(directed = FALSE) %>%
    set_vertex_attr(name = "color", value = with(nodes, as.character(group)[match(names(V(.)), id)])) %>%
    set_vertex_attr(name = "label", value = with(nodes, label[match(names(V(.)), label)])) %>%
    set_vertex_attr(name = "size", value = 10) %>%
    set_edge_attr(name = "curved", value = TRUE)

and then plot it

plot(g, layout = layout_with_fr)

enter image description here

ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81