Search code examples
rigraphbipartite

Node order in bipartite igraph


I have following adjacency matrix "dat":

dat <- read.table(text = '     TZ1   TZ2   TZ3   TZ4
  RSP1 0.456 0.232 0.234 0.000
  RSN1 0.248 0.613 0.754 0.413
  RSP2 0.206 0.000 0.493 0.000
  RSN2 0.000 0.000 0.000 0.000
  RSP3 0.000 0.000 0.218 0.000
  RSN3 0.000 0.000 0.000 0.000
  RSP4 0.000 0.000 0.000 0.851
  RSN4 0.000 0.000 0.000 0.000' ) %>%
    as.matrix()

and used the below code to make the bipartite

g<-graph_from_incidence_matrix(dat, directed = TRUE, mode = "out", multiple = FALSE, weighted = T, add.names = NULL)
V(g)$color <- ifelse(V(g)$type, "lightblue", "salmon")
V(g)$shape <- ifelse(V(g)$type, "square","circle")
V(g)$frame.color <-  "gray" 
V(g)$size <- 18
E(g)$color <- "blue"
plot.igraph(g, edge.width=E(g)$weight*5, layout=layout.bipartite,edge.arrow.size=0.5,
 vertex.label.cex = 0.8, vertex.label.color = "black", vertex.shape=V(g)$shape, vertex.size=degree(g)*5)

The order of the nodes is however not according to below

RSP1    RSN1    RSP2    RSN2    RSP3    RSN3    RSP4    RSN4

and

TZ1   TZ2   TZ3   TZ4

How can we make graph with above ordering of the nodes?


Solution

  • So a lot of the layout functions in igraph, layout.bipartite included, focus on minimizing edge crossings:

    The layout is created by first placing the vertices in two rows, according to their types. Then the positions within the rows are optimized to minimize edge crossings,

    If you want to control the node locations, then you will have to make a custom layout by making a matrix with x and y positions in the columns and the rows in the same order as the V(g). purrr can help you out here:

    Rs <- V(g)$name[grepl('^R', V(g)$name)] %>%
      purrr::imap(function(x, i){
        c(i, 2)
      }) %>%
      do.call(rbind, .)
    
    Ts <- V(g)$name[grepl('^T', V(g)$name)] %>%
      purrr::map2(3:6, function(x, i){
        c(i, 1)
      }) %>%
      do.call(rbind, .)
    
    l <- rbind(Rs, Ts)
    

    which will give you a matrix of:

          [,1] [,2]
     [1,]    1    2
     [2,]    2    2
     [3,]    3    2
     [4,]    4    2
     [5,]    5    2
     [6,]    6    2
     [7,]    7    2
     [8,]    8    2
     [9,]    3    1
    [10,]    4    1
    [11,]    5    1
    [12,]    6    1
    

    enter image description here