Written and maintained by CASRAI Editorial Board
Last updated
igraph is a high-performance open-source library designed for complex network analysis and graph theory. Built around a compiled C/C++ computational core with comprehensive interfaces in R, Python, and Mathematica, igraph allows academic researchers to construct, manipulate, and analyze networks containing millions of vertices and edges with minimal memory overhead.
What it is used for in research
In empirical research disciplines—particularly sociology, anthropology, computational social science, and bibliometrics—relational data forms the foundation of structural inquiry. Researchers use igraph to model kinship ties, institutional co-authorship patterns, social interaction graphs, and communication structures. The primary advantage of igraph is its computational architecture: by executing path-finding algorithms, graph partitioning, and matrix operations in optimized C, the library eliminates the memory bottlenecks and performance slowdowns often encountered in interpreted scripting languages.
While pure-Python libraries such as NetworkX excel in exploratory data analysis and rapid algorithmic prototyping on smaller graph topologies, igraph scales efficiently to dense networks and massive administrative datasets. In interdisciplinary research spanning computational sociology and systems biology, igraph data structures also serve as foundational backends for specialized statistical toolkits, such as clusterProfiler, when evaluating relational subnetworks and functional clusters.
Core Capabilities in Empirical Work
- Topological and Metric Calculation: Computing vertex-level degree, betweenness, closeness, eigenvector, and PageRank centralities across weighted or directed structures.
- Community Detection: Partitioning networks into cohesive structural modules using modularity optimization algorithms, including the Leiden and Louvain techniques.
- Graph Generators: Creating empirical baseline null models, including Erdős-Rényi random graphs, Watts-Strogatz small-world models, and Barabási-Albert preferential attachment networks.
- Interoperability: Importing and exporting established network interchange formats, including GraphML, Pajek (.net), edge lists, and adjacency matrices.
Install or access (official source only)
The igraph software ecosystem is distributed through official programming language package repositories, with its native source code maintained under the GNU General Public License (GPL-2 | GPL-3).
R Package Installation
The R interface (igraph) is maintained on the Comprehensive R Archive Network (CRAN) under permanent identifier DOI: 10.32614/CRAN.package.igraph. It requires R (≥ 3.5.0) and compiled C++ dependencies managed through cpp11.
# Install stable release from CRAN
install.packages("igraph")
# Load package in your R session
library(igraph)
Python Package Installation
The Python interface is distributed via the Python Package Index (PyPI) under the package name igraph (formerly python-igraph). Pre-compiled binary wheels include the bundled C core for major operating systems (Linux, macOS, Windows).
# Install stable release from PyPI
pip install igraph
# Optional: Install Cairo bindings for network visualization
pip install cairocffi
Step-by-step task
The following task demonstrates how to construct, analyze, and partition an empirical social network in R from raw tabular datasets (an edge list and a node attribute table), using commands verified against official package documentation.
When preparing tabular input, researchers often organize relationship data into structured tables using data manipulation libraries like pandas add column workflows in Python or equivalent data frame pipelines before passing arrays to igraph.
Step 1: Format Relational Tables
Relational data in research is typically maintained as two data frames: an edge list containing source and target node identifiers, and a vertex table containing unique node attributes (such as institutional affiliation or department).
# Create an edge list data frame
edges_df <- data.frame(
from = c("ResearcherA", "ResearcherA", "ResearcherB", "ResearcherC", "ResearcherD"),
to = c("ResearcherB", "ResearcherC", "ResearcherD", "ResearcherD", "ResearcherE"),
weight = c(3, 1, 5, 2, 4),
stringsAsFactors = FALSE
)
# Create a vertex attributes data frame
nodes_df <- data.frame(
name = c("ResearcherA", "ResearcherB", "ResearcherC", "ResearcherD", "ResearcherE"),
dept = c("Sociology", "Sociology", "Anthropology", "Anthropology", "Economics"),
stringsAsFactors = FALSE
)
Step 2: Construct Graph from Data Frame
Construct the igraph object using graph_from_data_frame(). The first argument specifies the edge relationships and edge attributes, while the vertices argument binds vertex attributes directly to node records.
# Build an undirected graph object
net <- graph_from_data_frame(d = edges_df, vertices = nodes_df, directed = FALSE)
# Verify graph dimensions
vcount(net) # Returns number of vertices (5)
ecount(net) # Returns number of edges (5)
Step 3: Calculate Structural Centrality Metrics
Calculate vertex degree and betweenness centrality to evaluate individual structural positioning within the relational network.
# Degree centrality (number of collaborative ties)
V(net)$deg <- degree(net, mode = "all")
# Normalized betweenness centrality (brokerage role)
V(net)$betw <- betweenness(net, directed = FALSE, normalized = TRUE)
# View computed node attributes
as_data_frame(net, what = "vertices")
Step 4: Detect Communities Using the Leiden Algorithm
Partition the network into structural clusters using the Leiden community detection algorithm, which optimizes modularity while avoiding disconnected community artifacts.
# Execute Leiden community detection
comm <- cluster_leiden(net, objective_function = "modularity", weights = E(net)$weight)
# Inspect community membership
membership(comm)
modularity(comm)
Step 5: Export Network to Standard Interchange Format
Save the network, including all computed attributes and partitions, to a standard GraphML file for cross-platform replication or archiving.
# Export graph to GraphML format
write_graph(net, file = "collaborations.graphml", format = "graphml")
Output and how to read it
When an igraph object is printed to the console in R, it returns a standardized multi-line diagnostic summary that describes the structural characteristics of the graph.
IGRAPH UNW- 5 5 --
+ attr: name (v/c), dept (v/c), deg (v/n), betw (v/n), weight (e/n)
+ edges from UNW- (vertex names):
[1] ResearcherA--ResearcherB ResearcherA--ResearcherC ResearcherB--ResearcherD
[4] ResearcherC--ResearcherD ResearcherD--ResearcherE
Deciphering the Header Flags
- First letter (U or D):
Uindicates an undirected graph;Dindicates a directed graph. - Second letter (N or -):
Nconfirms that vertices have anameattribute (named graph). - Third letter (W or -):
Windicates that edges have a numericweightattribute. - Fourth letter (B or -):
Bdenotes a bipartite (two-mode) graph structure. - Numbers: The two subsequent integers report the total vertex count (5) and edge count (5).
- Attribute descriptors:
(v/c)denotes a vertex attribute of character type;(e/n)denotes an edge attribute of numeric type.
Reading Community Detection Output
The cluster_leiden() function returns a community object containing a $membership vector and a $modularity score. Modularity values range from -0.5 to 1.0; in empirical sociology, a modularity score exceeding 0.3 generally indicates that the network exhibits substantial community subdivision rather than random edge distribution.
Troubleshooting
Error: “Cannot create graph from data frame: Some vertex names in edge list are not in vertex data frame”
Cause: The d edge list contains source (from) or target (to) identifiers that do not appear in the name column of the vertices data frame.
Resolution: Ensure that every identifier in the edge list is present in the vertex table by validating set membership before graph creation: stopifnot(all(edges_df$from %in% nodes_df$name) && all(edges_df$to %in% nodes_df$name)).
Index Discrepancy Between R and Python (1-based vs. 0-based)
Cause: In R, vertex indexing starts at 1 (V(g)[1] refers to the first vertex), whereas in Python, indexing is strictly 0-based (g.vs[0] refers to the first vertex). Translating code directly between languages without adjusting for index offsets produces off-by-one subsetting errors.
Resolution: Reference vertices by their unique string identifiers (V(g)["ResearcherA"] in R or g.vs.find(name="ResearcherA") in Python) rather than raw integer row indices.
Python Plotting Error: NotImplementedError / Missing Cairo Backend
Cause: Executing igraph.plot(g) in Python requires the Cairo 2D graphics library. If Cairo or cairocffi is not installed in the active virtual environment, igraph cannot render graphics.
Resolution: Install cairocffi via pip install cairocffi, or redirect visualization to a standard Matplotlib axis: import matplotlib.pyplot as plt; fig, ax = plt.subplots(); ig.plot(g, target=ax).
Disconnected Clusters During Modularity Optimization
Cause: The standard Louvain algorithm (cluster_louvain) optimizes global modularity but can inadvertently aggregate disconnected graph components into a single nominal community.
Resolution: Use cluster_leiden() instead. The Leiden algorithm incorporates a refinement phase that guarantees all identified communities are internally connected subgraphs.
Free alternatives
When selecting network analysis tools for academic research, analysts balance execution speed, memory footprint, scripting interfaces, and visualization requirements. As datasets scale, teams often compare data engine backends using Polars vs pandas before selecting their network software.
| Software | Primary Core and Interface | Computational Scalability | Best Research Use Case | License |
|---|---|---|---|---|
| igraph | Compiled C/C++ core with R, Python, and C interfaces | High; handles millions of nodes and edges in memory | Statistical network analysis, programmatic scripting pipelines, and reproducible modeling | GPL-2 | GPL-3 |
| NetworkX | Pure Python | Moderate; memory-intensive on networks exceeding 100,000 nodes | Prototyping, algorithm exploration, and Python data science teaching | 3-Clause BSD |
| graph-tool | C++ with OpenMP parallelization and Python interface | Extremely high; multi-threaded high-performance computing | Massive graph topologies and statistical inference of stochastic block models | GPL-3 |
| Gephi | Java desktop application with interactive GUI | Moderate; constrained by Java Virtual Machine (JVM) heap | Interactive visual exploration, layout formatting, and manual network inspection | GPL-3 / CDDL |
FAQ
What is the difference between igraph in R and python-igraph?
Both packages share the same underlying C core library, ensuring identical performance and algorithmic implementations for graph operations. The primary difference lies in language idioms: the R interface (igraph) uses 1-based indexing and integrates with R data frame workflows, while the Python interface (igraph) uses 0-based indexing and integrates with Python data structures and NumPy.
Does igraph support directed and weighted networks?
Yes. igraph natively accommodates directed, undirected, weighted, and bipartite graphs. In R, directionality is designated during creation via directed = TRUE or FALSE, while edge weights can be assigned as an edge attribute (E(g)$weight) and recognized automatically by shortest-path and community detection functions.
How does igraph compare to NetworkX for large-scale social networks?
igraph is substantially faster and uses far less memory than NetworkX on large graphs because its data structures and traversal algorithms are compiled in native C. NetworkX is implemented in pure Python, making its internal code easier to read and extend, but significantly slower when computing centrality metrics or paths across networks with hundreds of thousands of vertices.
Why is the Leiden algorithm preferred over the Louvain algorithm in igraph?
The Leiden algorithm (cluster_leiden) addresses a well-documented flaw in the Louvain method (cluster_louvain), wherein communities identified by Louvain can become internally disconnected or poorly separated. Leiden guarantees that communities are connected and converges to a stable, well-partitioned solution much faster.







