How would one go about separating nodes into areas of the canvas given their (discrete) attribute

I want to separate nodes given their attribute (a, b, c, d, e) such that attributes (a,b,c,d) are placed in the corners, while those with attribute d roam freely (are placed) by some algorithm.

Is that possible?

I know I can alter the placement from the layout functions like:

mylayout <- layout_with_kk(g)

and then modify the placement of some nodes, but then the others are not replaced, which might leave me with a “suboptimal” placement.

Test graph:

# some graph (similar to my problem)
a <- matrix(0,10,10)
for(i in 1:10){
    a[i,] <- c(rep(0, 4),sample(c(0,1), 6, replace = T))
}
a[2,] <- c(rep(0, 4),sample(c(0,1), 6, replace = T))
a[3,] <- c(rep(0, 4),sample(c(0,1), 6, replace = T))
a[4,] <- c(rep(0, 4),sample(c(0,1), 6, replace = T))
colnames(a) <-  c("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")
g <- igraph::graph_from_adjacency_matrix(a,
                                         mode = "undirected",
                                         add.colnames = NULL)
attribute <- c(rep("d", 6), "a", "b", "c", "d")
g <- igraph::set_vertex_attr(g, "attA", value = attribute)
# viz
GGally::ggnet2(g,
               label = TRUE,
               mode = layout_(g, as_tree(root = V(g)[1:4]))
)

Look into the minx, maxx / miny, maxy parameters of layout_with_kk() and layout_with_fr(), which allow restricting each vertex into its own specific bounding box. The position of a vertex can be fixed by using the same minimum and maximum. For free (i.e. unconstrained) vertices, use -Inf and Inf as the minimum/maximum.

P.S. I deleted your other question since it was essentially a duplicate of this one. Feel free to ask further question on the topic within this thread.

Thank you! @szhorvat

Minor issue as I have not fully figured it out:
Without using the minx/maxx/miny/maxy settings, I get the following result based on the weight (which is in integer steps).

it’s great. i just want to separate the nodes by group adherence, as suggested by you.

but when using the minx/maxx/miny/maxy specifications, i get a separated graph, but not as nicely spaced from the center in integer steps.

(see next comment, because of one media item per post limit)

Do you have an idea, how to fix that?

I have seen similar problems with fixing vertices. I believe that the naïve FR and KK algorithms are not well suited for fixing vertices. This works well in many cases, but things can easily go wrong.

My advice is to try to avoid putting too much stress in the system. When you fix vertices, try to set their locations, and their distances, in such a way that the net force wouldn’t be too large on any vertex. I.e. the layout should be reasonably natural even with fixing points. Experiment with both FR and KK and see which works better. Refer to the C documentation to see what the approximate natural length of edges would be with either FR or KK—this should be helpful when designing your layout. Seeing that you have a star graph, if you want weights to control edge lengths more naturally, it may be worth taking their cube root.

Without knowing the details, it’s hard to tell what exactly goes wrong in your specific example, but i hope this helps a bit.

1 Like