Search code examples
rggplot2igraphbipartiteggnetwork

How to plot one-mode unipartite network in R from a bipartite matrix


I have a matrix in which the columns are predators and the rows are the prey they eat. I want to plot an one-mode network of the predators. So, each node it will be the predators and the link/edges will connect the predators that share prey.

My original dataset has much more zero that the example below, but I got close to what I want to plot with the code below:

m <- matrix(ncol=40,nrow=20)
m <- apply(m, c(1,2), function(x) sample(c(0:4),1)) 
colnames (m) <- c(sprintf("C%02d", seq(1,40)))
rownames (m) <- c(sprintf("R%02d", seq(1,20)))


install.packages("GGally")
library(GGally)

ggnet2(as.one.mode(m, project="higher"), label=T,
       node.size = 2, node.color = "black",
       edge.size = 0.1, edge.color = "grey",
       layout.par = list(cell.jitter = 3))

The nodes on my plot are overlapping a lot (as in the image, that is from my original dataset). This is the plot of my original dataset

Any ideas on how to change the nodes overlapping? I tried to change layout parameters already.

Also, I couldn't plot this one-mode/unipartite network using igraph. Any ideas on how to plot this type of network from a bipartite matrix with igraph?

Any sugestions on how to improve the visualization of this type of network is welcome, including using other packages and functions


Solution

  • The code you provide generates a fairly dense graph, so it will be tricky to find a layout without overlapping in this case. You could look into some options other than "ball and stick" layouts, and see if those work for you.

    I find the combination of tidygraph and ggraph very powerful and intuitive for working with networks. A quick demo of projecting and plotting a bipartite graph:

    library(tidygraph)
    library(ggraph)
    
    m <- matrix(ncol=40,nrow=20)
    m <- apply(m, c(1,2), function(x) sample(c(0:4),1)) 
    colnames (m) <- c(sprintf("C%02d", seq(1,40)))
    rownames (m) <- c(sprintf("R%02d", seq(1,20)))
    
    tg <- as_tbl_graph(m)
    
    tg_proj <- igraph::bipartite_projection(tg, which=TRUE) |> 
        as_tbl_graph()
    
    midw <- tg_proj %E>% pull(weight) |> median()
    
    ggraph(tg_proj, layout="kk") +
        geom_edge_link(aes(col=weight), alpha=0.5, edge_width=1.2) +
        geom_node_point() +
        scale_edge_color_gradient2(midpoint=midw) +
        theme(plot.background=element_rect(color="gray40"))
    

    enter image description here