ggbipart is a set of R functions for
plotting bipartite networks, using ggplot2,
network, and igraph graphics. The
ggplot2-based routines rely heavily on code developed by
Francois Briatte for the ggnet library
(now part of GGally).
Bipartite networks are a special type of network where nodes belong to two distinct sets (modes), and links only connect nodes of different sets. As with other networks, bipartite structures can be binary (only the presence/absence of a link is recorded) or quantitative (weighted), where links carry a variable importance or weight. Everything starts from an adjacency (incidence) matrix. Here we use matrices describing ecological interactions between animal frugivores and the plants whose fruits they eat. By convention in these examples, rows are plant species and columns are animal species.
The package ships two well-sampled plant-frugivore interaction
matrices from southern Spain in inst/extdata/, retrievable
with system.file(). Both are weighted adjacency matrices;
the comment header lines are stripped with
comment.char = "#".
# Nava de las Correhuelas (26 plants x 36 frugivores).
nch <- as.matrix(read.csv(
system.file("extdata", "sdw01_adj_fru.csv", package = "ggbipart"),
comment.char = "#", row.names = 1, check.names = FALSE))
# Hato Raton (16 plants x 17 frugivores).
hr <- as.matrix(read.csv(
system.file("extdata", "sdw02_adj_fru.csv", package = "ggbipart"),
comment.char = "#", row.names = 1, check.names = FALSE))
dim(nch)
#> [1] 26 36
dim(hr)
#> [1] 16 17Adjacency matrices are turned into the graph objects the plotting
functions expect. bip_init_network() returns a
network object; bip_init_igraph() returns an
igraph object. Both encode the two modes and carry the edge
weights.
hr.net <- bip_init_network(hr) # network object
hr.ig <- bip_init_igraph(hr) # igraph object
hr.net
#> Network attributes:
#> vertices = 33
#> directed = FALSE
#> hyper = FALSE
#> loops = FALSE
#> multiple = FALSE
#> bipartite = 16
#> total edges= 121
#> missing edges= 0
#> non-missing edges= 121
#>
#> Vertex attribute names:
#> mode vertex.names
#>
#> Edge attribute names:
#> weightsTwo small helpers underlie the plotting routines.
vectorize() converts an adjacency matrix into a long,
three-column edge table, and bip_edgewt() returns
log-scaled edge weights suitable for mapping to line widths.
head(vectorize(hr))
#> Var2 Var1 as.vector(mat)
#> 1 Pistacia.lentiscus Sylvia.atricapilla 1370
#> 2 Pistacia.lentiscus Sylvia.borin 336
#> 3 Pistacia.lentiscus Erithacus.rubecula 317
#> 4 Pistacia.lentiscus Sylvia.melanocephala 49
#> 5 Pistacia.lentiscus Turdus.merula 115
#> 6 Pistacia.lentiscus Turdus.philomelos 14
summary(bip_edgewt(hr, x = 30))
#> Min. 1st Qu. Median Mean 3rd Qu. Max.
#> 0.3958 1.9520 4.5628 6.8343 11.2472 30.0000network back endbip_qtplot() draws a weighted (quantitative) bipartite
network directly from the adjacency matrix, scaling edge widths by
interaction strength.
bip_binplot() plots a network object; it is
well suited to binary (presence/absence) webs.
igraph back endbip_igplot() renders the same network through
igraph, using the adjacency matrix (for node counts and
edge scaling) and the igraph object.
ggplot2 graphs with bip_ggnetbip_ggnet() builds the plot within the
ggplot2 framework via GGally::ggnet2.
ggnet2 automatically detects two-mode graphs and
understands arguments of the form
[color, shape, size] = "mode", mapping the two modes to the
ggnet2 classes. The returned object is a regular
ggplot, so it can be extended with + in the
usual way.
Colours for the two modes are controlled with the
palette argument (its default is
c(A = "grey", P = "gold")). You can override it and layer
on extra ggplot2 geoms – here we colour by mode and add
node labels.
col <- c("P" = "#FC9272", "A" = "#9ECAE1")
bip_ggnet(hr.net, hr,
size = 7, shape = "mode", color = "mode",
palette = col, layout.exp = 0.25) +
geom_text(aes(label = network.vertex.names(hr.net)),
color = "black", size = 3) +
theme(legend.position = "none")bip_railway() uses the classic two-parallel-columns
layout familiar from the bipartite package, with each mode
on its own axis.
Bascompte, J. & Jordano, P. (2014) Mutualistic Networks. Princeton University Press, Princeton, NJ.
Pocock, M.J.O. et al. (2016) The visualisation of ecological networks, and their use as a tool for engagement, advocacy and management. Advances in Ecological Research 54, 41-85.
sessionInfo()
#> R version 4.5.3 (2026-03-11)
#> Platform: aarch64-apple-darwin20.0.0
#> Running under: macOS 27.0
#>
#> Matrix products: default
#> BLAS/LAPACK: /Users/pedro/.claude-science/conda/envs/r-package-dev/lib/libopenblas.0.dylib; LAPACK version 3.12.0
#>
#> locale:
#> [1] C
#>
#> time zone: Europe/Madrid
#> tzcode source: system (macOS)
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] igraph_2.3.3 network_1.20.0 ggbipart_0.1.3 ggplot2_4.0.3
#>
#> loaded via a namespace (and not attached):
#> [1] Matrix_1.7-6 gtable_0.3.6 jsonlite_2.0.0
#> [4] dplyr_1.2.1 compiler_4.5.3 tidyselect_1.2.1
#> [7] ggstats_0.14.0 tidyr_1.3.2 jquerylib_0.1.4
#> [10] scales_1.4.0 yaml_2.3.12 fastmap_1.2.0
#> [13] GGally_2.4.0 lattice_0.23-1 coda_0.19-4.1
#> [16] R6_2.6.1 generics_0.1.4 knitr_1.51
#> [19] tibble_3.3.1 statnet.common_4.13.0 bslib_0.12.0
#> [22] pillar_1.11.1 RColorBrewer_1.1-3 rlang_1.3.0
#> [25] cachem_1.1.0 xfun_0.60 sass_0.4.10
#> [28] S7_0.2.2 otel_0.2.0 cli_3.6.6
#> [31] withr_3.0.3 magrittr_2.0.5 digest_0.6.39
#> [34] grid_4.5.3 lifecycle_1.0.5 vctrs_0.7.3
#> [37] sna_2.8 evaluate_1.0.5 glue_1.8.1
#> [40] farver_2.1.2 purrr_1.2.2 rmarkdown_2.31
#> [43] tools_4.5.3 pkgconfig_2.0.3 htmltools_0.5.9