Fix position of nodes with layout_with_fr

I would like to optimise the positions of the first node set in a two-mode graph based on the positions of a first node set. I saw in the description of layout_with_fr() that positions of egos and as I understood also of several nodes can be fixed. The following example shows this using lon lat values for 26 nodes of the first node set and -inf for 26 nodes of the second node set.

# sample graph and transform to two-mode network
g <- sample_pa(26, m=2)
tm<-get.adjacency(g, names=FALSE)
g <- graph_from_incidence_matrix(as.matrix(tm, time = max(events$time)))
# lon lat data for the first node-set of the two-mode network
lon <- c(8.156847,9.416345,9.368596,7.625363,7.702396,7.615194,7.073961,6.133073,9.06578,9.628154,7.156132,8.110061,6.780079,8.405384,8.24331,9.275258,8.591709,7.639228,8.756584,9.092979,8.808903,8.628586,6.657902,7.604754, 8.537324, 8.655167)
lat <-c(47.40973,47.31729,47.36624,46.82192,47.45168,47.56484,46.71842,46.22047,46.9811,46.65624,47.3507,47.06778,46.99553,46.92681,46.85235,47.23359,47.71354,47.30422,47.06192,47.56883,46.29559,46.77191,46.57009,46.20956,47.1573,47.41282)

# limits as in the example of ?layout_with_fr()
minC <- rep(-Inf, vcount(g))
maxC <- rep(Inf, vcount(g))
minC[1:26] <- lon
maxC[1:26] <- lat

set.seed(1)
co <- layout_with_fr(g, minx=minC, maxx=minC,
                 miny=maxC, maxy=maxC)
co[1,]

co has -Inf values which I get because I changed the option in layout_with_fr from minx=minC, maxx=maxC,miny=minC, maxy=maxC to minx=minC, maxx=minC,miny=maxC, maxy=maxC. How can I get this to work so that layout_with_fr optimises the positions conditional on lon lat values?

I would like to run after:

plot(g, layout=co, vertex.size=30, edge.arrow.size=0.2,
 vertex.label="", rescale=FALSE,
 xlim=range(co[,1]), ylim=range(co[,2]), vertex.label.dist=0,
 vertex.label.color="red", vertex.color = ifelse(V(g)$type == F, "red", "blue"))

It is not possible to fix the position of vertices in the current version.

Perhaps to add to @szhorvat 's remark, where did you read that node positions could be fixed @merretich? Perhaps we should clarify some documentation.

Ah I see, I was hoping to achieve this and expected it to work from the example code in the documentation. It would be great to have this implemented @vtraag @szhorvat. Would it be difficult to allow for fixing nodes of several vertices? But it does allow fixing nodes right? Or am I understanding something wrong?

@vtraag from reading the help file under options, I thought that they would allow fixing node positions of several nodes through a specified vector.

minx   If not  `NULL` , then it must be a numeric vector that gives 
       lower boundaries for the ‘x’ coordinates of the vertices. The 
       length of the vector must match the number of vertices in 
       the graph.

I would be interested in using this for a publication on water cooperation.

I think the older implementation of Fruchterman-Reingold had this feature, but for some reason it was re-implemented, and this feature was not re-added. I was not around at the time so I don’t know the details. Maybe someone else can clarify.

@szhorvat okay. Thank you for the support! That’s unfortunate, because I think that this feature would be highly valuable for research in political science and Economics. Basically, for any two-mode network where actors have geographical positions, it would improve understandability of the graph. Would it be possible to reimplement the code of the old Fruchtermann-Reingold? Or could I still use the old version?

layout_with_drl can fix positions of vertices. See if it works for you.

Great thank you very much for the suggestion. I will try and let you know.

I’m sorry, I may have been wrong in stating that this feature was present in the past. My memory seems to be failing me (or at least I can’t find the feature in the old documentation).

I hope layout_with_drl will work for you.

Working on the above example, I can use

co <- layout_with_drl(g, use.seed = T, seed = cbind(lon, lat))

but using the option to fix nodes (26 of the first nodeset, allowing the positions 26 nodes of the second node-set in the two-mode graph to optimise)

co <- layout_with_drl(g, use.seed = T, seed = cbind(lon, lat), fixed = T)

yields

Error in layout_with_drl(g, use.seed = T, seed = cbind(lon, lat), fixed = T) : 
  At DensityGrid.cpp:228 : Exceeded density grid in DrL, Internal DrL error

Not sure how I should understand this error

This was not correctly implemented in the C code of igraph_layout_drl see igraph Reference Manual. We discussed this at some point in issue #916.

To be sure, you only see this problem when setting fixed = T?

@vtraag Yes. Using layout_with_drl() without the fixed = T option, the first 5 columns are different than those specified in lon and lat

            [,1]       [,2]
 [1,] -153.01654  285.15234
 [2,]   11.96959   14.69094
 [3,]   11.15128   14.86336
 [4,]   11.43242   15.67593
 [5,]   12.01517   16.36695

cbind(lon, lat)[1:5,] are the following entries:

           lon      lat
 [1,] 8.156847 47.40973
 [2,] 9.416345 47.31729
 [3,] 9.368596 47.36624
 [4,] 7.625363 46.82192
 [5,] 7.702396 47.45168

Using fixed = T gives the error. Without fixed = T, I do not get an error

It might be a bug that you receive this error. As said, it seems that fixing nodes does not work at the moment in the C core, but it should not raise an error anyway. We should also clarify this in the R igraph documentation.

Could you report this at https://github.com/igraph/rigraph/issues, with a complete minimal working example, including the graph data?