High performance graph data structures and algorithms for Python
—
Comprehensive support for reading and writing graphs in various formats including GraphML, GML, Pajek, DIMACS, and more. igraph provides seamless data interchange with other network analysis tools and databases.
Load graphs from files in multiple formats with automatic format detection and manual specification options.
class Graph:
@classmethod
def Read(cls, filename, format=None, **kwargs):
"""
Read graph from file with automatic format detection.
Parameters:
- filename: str, path to input file
- format: str, file format (None for auto-detection)
Supported: "edgelist", "ncol", "lgl", "graphml", "gml",
"net" (pajek), "dimacs", "graphdb", "pickle", "svg"
- **kwargs: format-specific parameters
Returns:
Graph object loaded from file
"""
@classmethod
def Read_Edgelist(cls, filename, directed=True):
"""
Read simple edge list format.
Parameters:
- filename: str, input file path
- directed: bool, whether edges are directed
Returns:
Graph from edge list
"""
@classmethod
def Read_Ncol(cls, filename, names=True, weights="auto", directed="auto"):
"""
Read NCOL format (name-based edge list).
Parameters:
- filename: str, input file
- names: bool, whether file contains vertex names
- weights: str/bool, weight handling ("auto", True, False, or attribute name)
- directed: str/bool, direction handling ("auto", True, False)
Returns:
Graph with vertex names and optional weights
"""
@classmethod
def Read_GraphML(cls, filename, index=0):
"""
Read GraphML format.
Parameters:
- filename: str, GraphML file path
- index: int, graph index (for files with multiple graphs)
Returns:
Graph with full attribute preservation
"""Usage Examples:
import igraph as ig
# Automatic format detection
g1 = ig.Graph.Read("network.graphml")
g2 = ig.Graph.Read("edges.txt") # Auto-detects as edgelist
# Explicit format specification
g3 = ig.Graph.Read("data.net", format="pajek")
# Simple edge list
g4 = ig.Graph.Read_Edgelist("simple_edges.txt", directed=False)
# Named vertices with weights
g5 = ig.Graph.Read_Ncol("weighted_network.ncol", weights=True)
# GraphML with attributes
g6 = ig.Graph.Read_GraphML("attributed_network.graphml")
# Handle multiple graphs in one file
for i in range(3): # If file contains 3 graphs
g = ig.Graph.Read_GraphML("multi_graph.graphml", index=i)
print(f"Graph {i}: {g.vcount()} vertices, {g.ecount()} edges")Save graphs to files in various formats for interoperability with other tools.
class Graph:
def write(self, filename, format=None, **kwargs):
"""
Write graph to file.
Parameters:
- filename: str, output file path
- format: str, output format (None for auto-detection from extension)
- **kwargs: format-specific options
Returns:
None
"""
def write_edgelist(self, filename):
"""
Write simple edge list.
Parameters:
- filename: str, output path
Returns:
None
"""
def write_ncol(self, filename, names=None, weights=None):
"""
Write NCOL format.
Parameters:
- filename: str, output path
- names: str/bool, vertex name attribute or True for indices
- weights: str/bool, edge weight attribute or True for equal weights
Returns:
None
"""
def write_graphml(self, filename):
"""
Write GraphML format with full attribute preservation.
Parameters:
- filename: str, output path
Returns:
None
"""
def write_gml(self, filename):
"""
Write GML format.
Parameters:
- filename: str, output path
Returns:
None
"""
def write_pajek(self, filename):
"""
Write Pajek NET format.
Parameters:
- filename: str, output path
Returns:
None
"""Usage Examples:
# Create sample graph with attributes
g = ig.Graph([(0,1), (1,2), (2,0), (1,3)], directed=False)
g.vs["name"] = ["Alice", "Bob", "Carol", "Dave"]
g.vs["age"] = [25, 30, 28, 35]
g.es["weight"] = [1.0, 2.5, 1.8, 0.9]
g.es["type"] = ["friend", "work", "family", "friend"]
# Save in different formats
g.write("network.graphml") # GraphML with all attributes
g.write("network.gml") # GML format
g.write("network.net") # Pajek format
g.write("edges.txt", format="edgelist") # Simple edge list
# Named edge list
g.write_ncol("named_edges.ncol", names="name", weights="weight")
# Simple formats
g.write_edgelist("simple.edges")
# Format-specific options
g.write("network.dot", format="dot") # Graphviz DOT formatSupport for domain-specific and research-oriented file formats.
class Graph:
@classmethod
def Read_Pajek(cls, filename):
"""
Read Pajek NET format.
Parameters:
- filename: str, Pajek file path
Returns:
Graph with Pajek-specific attributes
"""
@classmethod
def Read_GML(cls, filename):
"""
Read GML (Graph Modeling Language) format.
Parameters:
- filename: str, GML file path
Returns:
Graph with GML attributes
"""
@classmethod
def Read_Lgl(cls, filename, names=True, weights="auto"):
"""
Read LGL (Large Graph Layout) format.
Parameters:
- filename: str, LGL file path
- names: bool, vertex names present
- weights: str/bool, weight handling
Returns:
Graph from LGL format
"""
@classmethod
def Read_Dimacs(cls, filename, directed=False):
"""
Read DIMACS challenge format.
Parameters:
- filename: str, DIMACS file path
- directed: bool, directed graph
Returns:
Graph in DIMACS format
"""
def write_dimacs(self, filename, source=None, target=None, capacity=None):
"""
Write DIMACS flow format.
Parameters:
- filename: str, output path
- source: int, source vertex for flow problems
- target: int, sink vertex for flow problems
- capacity: str, edge capacity attribute
Returns:
None
"""Usage Examples:
# Domain-specific formats
pajek_g = ig.Graph.Read_Pajek("social_network.net")
gml_g = ig.Graph.Read_GML("biological_network.gml")
lgl_g = ig.Graph.Read_Lgl("large_network.lgl")
dimacs_g = ig.Graph.Read_Dimacs("flow_network.dimacs")
# Write DIMACS for flow problems
flow_graph = ig.Graph([(0,1), (0,2), (1,2), (1,3), (2,3)], directed=True)
flow_graph.es["capacity"] = [10, 10, 1, 10, 10]
flow_graph.write_dimacs("flow_problem.dimacs", source=0, target=3, capacity="capacity")
# Check format-specific attributes
if "coordinate" in pajek_g.vs.attributes():
print("Pajek file contained vertex coordinates")
if "weight" in gml_g.es.attributes():
print("GML file contained edge weights")Seamless conversion between igraph and NetworkX for accessing different algorithm implementations.
class Graph:
def to_networkx(self):
"""
Convert igraph Graph to NetworkX graph.
Returns:
NetworkX graph with preserved attributes
"""
@classmethod
def from_networkx(cls, graph):
"""
Create igraph Graph from NetworkX graph.
Parameters:
- graph: NetworkX graph object
Returns:
igraph Graph with converted attributes
"""Usage Examples:
try:
import networkx as nx
# Create igraph graph
ig_graph = ig.Graph.Barabasi(100, m=3, directed=False)
ig_graph.vs["betweenness"] = ig_graph.betweenness()
# Convert to NetworkX
nx_graph = ig_graph.to_networkx()
# Use NetworkX algorithms
nx_pagerank = nx.pagerank(nx_graph)
nx_clustering = nx.clustering(nx_graph)
# Convert back to igraph
nx_graph.graph["description"] = "Processed with NetworkX"
for node in nx_graph.nodes():
nx_graph.nodes[node]["nx_pagerank"] = nx_pagerank[node]
nx_graph.nodes[node]["nx_clustering"] = nx_clustering[node]
converted_back = ig.Graph.from_networkx(nx_graph)
# Compare results
print("NetworkX PageRank:", list(nx_pagerank.values())[:5])
print("igraph PageRank:", converted_back.pagerank()[:5])
except ImportError:
print("NetworkX not available")Support for graph databases and web-based data sources.
class Graph:
@classmethod
def Read_GraphDB(cls, filename, directed=True):
"""
Read GraphDB format.
Parameters:
- filename: str, GraphDB file path
- directed: bool, graph direction
Returns:
Graph from database format
"""
def write_svg(self, filename, layout=None, **kwargs):
"""
Write SVG vector graphics format.
Parameters:
- filename: str, SVG output path
- layout: Layout, vertex positions
- **kwargs: styling parameters
Returns:
None
"""
def write_dot(self, filename):
"""
Write Graphviz DOT format.
Parameters:
- filename: str, DOT output path
Returns:
None
"""Usage Examples:
# Database format
db_graph = ig.Graph.Read_GraphDB("graph_database.db")
# Vector graphics output
layout = g.layout_fruchterman_reingold()
g.write_svg("network.svg",
layout=layout,
vertex_size=20,
vertex_color="lightblue",
edge_color="gray")
# Graphviz format for external processing
g.write_dot("network.dot")
# Can then use: dot -Tpng network.dot -o network.pngEfficient storage formats for large graphs and fast I/O operations.
class Graph:
@classmethod
def Read_Pickle(cls, filename):
"""
Read Python pickle format (binary).
Parameters:
- filename: str, pickle file path
Returns:
Graph from pickle
"""
def write_pickle(self, filename):
"""
Write Python pickle format.
Parameters:
- filename: str, output path
Returns:
None
"""
def write_picklez(self, filename):
"""
Write compressed pickle format.
Parameters:
- filename: str, output path (will be compressed)
Returns:
None
"""Usage Examples:
import time
# Create large graph for performance testing
large_g = ig.Graph.Barabasi(10000, m=5)
large_g.vs["random_attr"] = [random.random() for _ in range(large_g.vcount())]
large_g.es["weights"] = [random.uniform(0.1, 2.0) for _ in range(large_g.ecount())]
# Compare I/O performance
formats_to_test = [
("pickle", large_g.write_pickle, ig.Graph.Read_Pickle),
("graphml", large_g.write_graphml, ig.Graph.Read_GraphML),
("gml", large_g.write_gml, ig.Graph.Read_GML)
]
for format_name, write_func, read_func in formats_to_test:
filename = f"large_graph.{format_name}"
# Write timing
start_time = time.time()
write_func(filename)
write_time = time.time() - start_time
# Read timing
start_time = time.time()
loaded_g = read_func(filename)
read_time = time.time() - start_time
# File size
import os
file_size = os.path.getsize(filename) / (1024*1024) # MB
print(f"{format_name}: Write {write_time:.2f}s, Read {read_time:.2f}s, Size {file_size:.1f}MB")
# Compressed pickle for space efficiency
large_g.write_picklez("large_graph.pkl.gz")Handle custom file formats and edge cases in data loading.
Usage Examples:
import csv
from io import StringIO
def read_custom_csv(filename, source_col=0, target_col=1, weight_col=None,
directed=True, skip_header=True):
"""Read graph from custom CSV format."""
edges = []
weights = []
with open(filename, 'r') as f:
reader = csv.reader(f)
if skip_header:
next(reader) # Skip header row
for row in reader:
source = row[source_col].strip()
target = row[target_col].strip()
edges.append((source, target))
if weight_col is not None:
weights.append(float(row[weight_col]))
# Create graph from edge list
g = ig.Graph.TupleList(edges, directed=directed)
if weight_col is not None:
g.es["weight"] = weights
return g
def write_custom_format(graph, filename, include_attributes=True):
"""Write graph in custom text format."""
with open(filename, 'w') as f:
# Write header
f.write(f"# Graph with {graph.vcount()} vertices and {graph.ecount()} edges\\n")
# Write vertices with attributes
if include_attributes and graph.vs.attributes():
f.write("# Vertices:\\n")
for v in graph.vs:
attrs = {attr: v[attr] for attr in v.attributes()}
f.write(f"v {v.index} {attrs}\\n")
# Write edges with attributes
f.write("# Edges:\\n")
for e in graph.es:
if include_attributes and e.attributes():
attrs = {attr: e[attr] for attr in e.attributes()}
f.write(f"e {e.source} {e.target} {attrs}\\n")
else:
f.write(f"e {e.source} {e.target}\\n")
# Usage
custom_g = read_custom_csv("network_data.csv", weight_col=2)
write_custom_format(custom_g, "custom_format.txt")
# Batch processing multiple files
import glob
def process_graph_files(pattern, output_dir):
"""Process multiple graph files and convert formats."""
files = glob.glob(pattern)
for file_path in files:
try:
# Try to read with auto-detection
g = ig.Graph.Read(file_path)
# Generate output filename
base_name = os.path.splitext(os.path.basename(file_path))[0]
output_path = os.path.join(output_dir, f"{base_name}.graphml")
# Save in standardized format
g.write_graphml(output_path)
print(f"Converted {file_path} -> {output_path}")
except Exception as e:
print(f"Failed to process {file_path}: {e}")
# Convert all network files to GraphML
process_graph_files("data/*.net", "converted/")
process_graph_files("data/*.gml", "converted/")Install with Tessl CLI
npx tessl i tessl/pypi-igraph