Could you please help me?
I love plotting networks with igraph
for R. One nice feature is drawing polygons around the communities detected by a given algorithm.
When you use one of the community detection algorithms built in igraph, that's pretty straightforward. Like in this example with a random bipartite graph:
library(igraph)
graph <- sample_bipartite(10, 10, p = 0.5)
graph
graph.lou = cluster_louvain(graph)
graph.lou$membership
length(graph.lou$membership)
plot(graph.lou, graph)
But how can I use another kind of input to draw those polygons?
For instance, I usually calculate modularity using the package bipartite
for R, because it has other algorithms that are better suited for two-mode networks.
So I'm trying to use the output from bipartite as an input for drawing community polygons in igraph. As in the following example:
library(bipartite)
matrix <- as_incidence_matrix(graph)
matrix
matrix.bec = computeModules(matrix, method = "Beckett")
modules <- module2constraints(matrix.bec)
modules
length(modules)
plot(modules, graph)
From the output of the computeModules
function I'm able to extract a vector with community memberships using the module2constraints
function. When I try to use it as a plotting input, I get this error message:
Error in xy.coords(x, y, xlabel, ylabel, log) :
'x' and 'y' lengths differ
Is it possible to use this output from bipartite
in igraph
, so polygons are automatically drawn around the communities?
I've looked into the documentation, searched here on StackOverflow, experimented some tricks, but found no solution.
Thank you very much!
I've found a solution, with help given in another question!
Actually, another way to draw polygons around communities in igraph
for R is by using the argument mark.groups
of the function plot
.
However, this argument accepts only lists of community membership. So, if you want to use an output of the package bipartite
in the format of a vector together with an igraph
object, you need to convert it to a list first.
The info contained in the vector modules
described in the original question needs to be complemented with vertex names and first become a data frame, then a list:
number <- seq(1:10)
row <- "row"
rowlabels <- paste(row, number, sep = "")
column <- "col"
columnlabels <- paste(column, number, sep = "")
matrix <- matrix(data = rbinom(100,size=1,prob=0.5), nrow = 10, ncol = 10,
dimnames = list(rowlabels, columnlabels))
library(bipartite)
matrix.bec <- computeModules(matrix, method = "Beckett")
modules <- module2constraints(matrix.bec)
df <- data.frame(c(rownames(matrix), colnames(matrix)), modules)
colnames(df) <- c("vertices", "modules")
list <- split(df$vertices, df$modules)
Now the object list
can be used as a drawing input together with an igraph
object:
library(igraph)
graph <- graph_from_incidence_matrix(matrix, directed = F)
plot(graph,
mark.groups = list)
That's one way to make bipartite
and igraph
talk to one another!
Thank you very much!