I'm plotting a bipartite (two-mode) network using igraph and ggraph.But the nodes are overlapping a lot, even though there is still space in the graphic window.
I would like to plot this using ggraph, and I know it's possible to plot with other packages, such as igraph and bipartite (but my networks do not come out nice enough from these packages).
library(igraph)library(ggraph)# data matrixdata <- matrix(0, nrow = 164, ncol = 32)pos_non_zero <- sample(1:5248, size = 300)data[pos_non_zero] <- sample(1:8, size = 300, replace = TRUE)colnames(data) <- paste0("plan", 1:ncol(data))rownames(data) <- paste0("ani", 1:nrow(data))# igraph objectgr_ob <- igraph::graph_from_biadjacency_matrix(data,weighted=T,directed=F)# ggraphpar(mar=c(0,0,0,0),mai=c(0,0,0,0)) # increasing the graphic window areaggraph(gr_ob, layout="bipartite") + geom_edge_link(alpha=0.3,color="gray50", aes(width = E(gr_ob)$weight/2)) + geom_node_point(size = 5,color = "blue",show.legend = F) + geom_node_label(size=2,aes(label=name), angle=90,fill ="NA", label.size=0) + guides(edge_color = "none", edge_width = "none")+ scale_y_continuous(expand = c(.15, .15))+ theme_void()Any idea on how to avoid theoverlap of the nodes? The labels overlap are not a problem for me in this case.
- This post seems relevant:stackoverflow.com/a/46231204/28479453 - even then, aradial graph plot might be a better fit?lailaps– lailaps2025-10-07 19:49:42 +00:00CommentedOct 7 at 19:49
- @lailaps thanks! As soon as I can I'm gonna check this post, but I saw that is done in igraph... there my graph is fitting better, but I don't like much the appearence. But I even going to try to do similar changes in my current code (with ggraph). The radial is not that interesting for me, but I like the look! Maybe for another network.mmmap– mmmap2025-10-09 19:20:50 +00:00CommentedOct 9 at 19:20
1 Answer1
I think a bipartite graph can meet your need.
First, you need to move the rowname to the first column, convert it to the data frame and change it to a long table. I also exclude rows with values "0".
library(dplyr)df <- cbind(Name = rownames(data), data) %>% as.data.frame() %>% pivot_longer(!Name, names_to = "Plan", values_to = "n") %>% mutate(n = as.numeric(n)) %>% filter(n > 0)Use the package calledbipartiteD3 to create the chart. But I want to sort the chart based on the 'n' to make the chart even more attractive.
SortPrim <- df %>% # Sorting for the first column (Name) group_by(Plan) %>% summarise(Total=sum(n))%>% arrange(desc(Total))SortSec <- df %>% # Sorting for the second column (Plan) group_by(Name) %>% summarise(Total=sum(n))%>% arrange(desc(Total))The chart created below can be further adjusted to meet your preference. I have set it to 'vertical' because it's a very long list. If you prefer a horizontal chart, as you provided in your question, you should change details from line 10. I still prefer the vertical version though. Read the documentation to make further adjustments.
library(bipartiteD3)bipartite_D3(df, colouroption = 'brewer', Orientation = 'vertical', ColourBy = 1, PercentageDecimals=1, PrimaryLab = 'Plan', SecondaryLab = 'Name', SiteNames = '', SortPrimary = SortPrim$Plan, SortSecondary = SortSec$Name, MainFigSize = c(500, 3600), IndivFigSize = c(200, 1300), BoxLabPos = c(20, 20), PercPos = c(110,110), BarSize = 20, MinWidth = 10, Pad=8, filename = 'Plot')Comments
Explore related questions
See similar questions with these tags.

