High performance graph data structures and algorithms for Python
—
Multi-backend visualization system supporting Cairo, matplotlib, and plotly for creating publication-quality graph visualizations. igraph provides extensive customization options for colors, shapes, sizes, and styling.
Core plotting functionality with the main plot function that automatically selects appropriate backends.
def plot(obj, target=None, bbox=(0,0,600,600), **kwds):
"""
Main plotting function for graphs and other objects.
Parameters:
- obj: Graph, Layout, Clustering, etc. - object to plot
- target: str/file, output target (filename, file object, or None for display)
- bbox: tuple, bounding box (left, top, right, bottom) or BoundingBox
- **kwds: keyword arguments for styling and layout
Common styling parameters:
- layout: Layout object or string (algorithm name)
- vertex_size: int/list, vertex sizes
- vertex_color: color/list, vertex colors
- vertex_label: str/list, vertex labels
- edge_width: float/list, edge widths
- edge_color: color/list, edge colors
- margin: int/tuple, plot margins
Returns:
Plot object (backend-dependent)
"""Usage Examples:
import igraph as ig
# Create sample graph
g = ig.Graph.Famous("Zachary") # Karate club network
layout = g.layout_fruchterman_reingold()
# Basic plot
ig.plot(g, layout=layout)
# Save to file
ig.plot(g, "karate_club.png", layout=layout, bbox=(800, 600))
# With styling
ig.plot(g,
layout=layout,
vertex_size=20,
vertex_color="lightblue",
vertex_label=g.vs.indices,
edge_width=2,
margin=50)
# Color by community
communities = g.community_leiden()
colors = ["red", "blue", "green", "yellow", "purple"]
vertex_colors = [colors[i % len(colors)] for i in communities.membership]
ig.plot(g,
layout=layout,
vertex_color=vertex_colors,
vertex_size=25,
vertex_frame_width=0,
edge_width=0.5,
bbox=(800, 600),
margin=30)Work directly with plot objects for fine-grained control and multi-step plotting.
class Plot:
def __init__(self, bbox=(0,0,600,600), palette=None):
"""
Create plot object.
Parameters:
- bbox: BoundingBox or tuple, plotting area
- palette: Palette, color palette for automatic coloring
"""
def add(self, obj, **kwds):
"""
Add object to plot.
Parameters:
- obj: object to add (Graph, Layout, etc.)
- **kwds: styling parameters
Returns:
None
"""
def save(self, fname=None):
"""
Save plot to file.
Parameters:
- fname: str, filename (extension determines format)
Returns:
None
"""
def show(self):
"""
Display plot in interactive window or notebook.
Returns:
None
"""
# Backend-specific classes
class CairoGraphDrawer:
"""Cairo-based graph drawing backend."""
class MatplotlibGraphDrawer:
"""Matplotlib-based graph drawing backend."""
class PlotlyGraphDrawer:
"""Plotly-based graph drawing backend."""Usage Examples:
from igraph.drawing import Plot, BoundingBox
from igraph.drawing.colors import RainbowPalette
# Create plot object
plot = Plot(bbox=BoundingBox(800, 600), palette=RainbowPalette())
# Add graph with custom styling
plot.add(g,
layout=layout,
vertex_size=g.degree(), # Size by degree
vertex_color=communities.membership,
vertex_label=[f"v{i}" for i in range(g.vcount())],
edge_width=[1 + w*2 for w in g.es["weight"]] if "weight" in g.es.attributes() else 1)
# Save in different formats
plot.save("network.png")
plot.save("network.pdf")
plot.save("network.svg")
# Display interactively
plot.show()Comprehensive color management with multiple palette types and color space conversions.
class Palette:
def get(self, index):
"""
Get color at index.
Parameters:
- index: int, color index
Returns:
Color, RGBA color tuple
"""
class GradientPalette(Palette):
def __init__(self, start_color, end_color, n=256):
"""
Gradient between two colors.
Parameters:
- start_color: color specification
- end_color: color specification
- n: int, number of gradient steps
"""
class RainbowPalette(Palette):
def __init__(self, n=256, start=0, end=None):
"""
HSV rainbow palette.
Parameters:
- n: int, number of colors
- start: float, starting hue (0-1)
- end: float, ending hue
"""
class ClusterColoringPalette(Palette):
def __init__(self, n):
"""
Palette optimized for distinguishable cluster colors.
Parameters:
- n: int, number of clusters
"""
# Color conversion functions
def color_name_to_rgb(color): ...
def hsv_to_rgb(h, s, v): ...
def hsl_to_rgb(h, s, l): ...
def rgb_to_hsv(r, g, b): ...Usage Examples:
from igraph.drawing.colors import (
GradientPalette, RainbowPalette, ClusterColoringPalette,
color_name_to_rgb, hsv_to_rgb
)
# Gradient palette for vertex values
values = g.betweenness()
max_val = max(values)
gradient = GradientPalette("white", "red", n=100)
vertex_colors = [gradient.get(int(v/max_val * 99)) for v in values]
# Rainbow palette for communities
n_communities = len(set(communities.membership))
rainbow = RainbowPalette(n_communities)
community_colors = [rainbow.get(i) for i in communities.membership]
# Cluster-optimized palette
cluster_palette = ClusterColoringPalette(n_communities)
optimal_colors = [cluster_palette.get(i) for i in communities.membership]
# Color conversions
red_rgb = color_name_to_rgb("red")
custom_hsv = hsv_to_rgb(0.3, 0.8, 1.0) # Green-ish
# Plot with different color schemes
ig.plot(g, layout=layout, vertex_color=vertex_colors,
vertex_size=20, bbox=(800, 600))Comprehensive styling system for vertices, edges, and overall plot appearance.
# Vertex styling parameters
vertex_styling = {
"vertex_size": "int/list - vertex sizes",
"vertex_color": "color/list - fill colors",
"vertex_frame_color": "color/list - border colors",
"vertex_frame_width": "float/list - border widths",
"vertex_shape": "str/list - shapes ('circle', 'square', 'triangle-up', etc.)",
"vertex_label": "str/list - text labels",
"vertex_label_size": "int/list - label font sizes",
"vertex_label_color": "color/list - label colors",
"vertex_label_family": "str - font family",
"vertex_label_angle": "float/list - label rotation angles",
"vertex_label_dist": "float/list - distance from vertex center",
"vertex_order": "list - drawing order",
}
# Edge styling parameters
edge_styling = {
"edge_width": "float/list - edge widths",
"edge_color": "color/list - edge colors",
"edge_curved": "bool/float/list - curvature (0=straight, 1=curved)",
"edge_arrow_size": "float/list - arrow head sizes",
"edge_arrow_width": "float/list - arrow head widths",
"edge_label": "str/list - edge labels",
"edge_label_size": "int/list - label font sizes",
"edge_label_color": "color/list - label colors",
"edge_loop_size": "float/list - self-loop sizes",
}
# Plot-level styling
plot_styling = {
"layout": "Layout/str - vertex positions or algorithm name",
"margin": "int/tuple - plot margins",
"bbox": "BoundingBox/tuple - plotting area",
"background": "color - background color",
"palette": "Palette - automatic color palette",
}Usage Examples:
# Advanced vertex styling
vertex_degrees = g.degree()
max_degree = max(vertex_degrees)
ig.plot(g,
layout=layout,
# Vertex appearance
vertex_size=[10 + d*2 for d in vertex_degrees], # Size by degree
vertex_color=communities.membership,
vertex_frame_color="black",
vertex_frame_width=1.5,
vertex_shape="circle",
# Vertex labels
vertex_label=g.vs.indices,
vertex_label_size=10,
vertex_label_color="white",
vertex_label_dist=0,
# Edge appearance
edge_width=0.8,
edge_color="gray",
edge_curved=0.1,
edge_arrow_size=1.0,
# Plot settings
margin=40,
background="white",
bbox=(1000, 800))
# Conditional styling based on properties
def style_by_centrality(graph, centrality_values):
"""Style vertices based on centrality scores."""
max_cent = max(centrality_values)
return {
'vertex_size': [5 + c/max_cent * 25 for c in centrality_values],
'vertex_color': ["red" if c > max_cent*0.7 else "lightblue" for c in centrality_values],
'vertex_frame_width': [3 if c > max_cent*0.7 else 1 for c in centrality_values]
}
betweenness = g.betweenness()
styling = style_by_centrality(g, betweenness)
ig.plot(g, layout=layout, **styling)Plotly backend for interactive visualizations suitable for web applications and notebooks.
# Plotly-specific plotting
def plot_plotly(graph, layout=None, **kwargs):
"""
Create interactive plotly visualization.
Parameters:
- graph: Graph object
- layout: Layout object or algorithm name
- **kwargs: plotly-specific styling options
Returns:
Plotly Figure object
"""Usage Examples:
# Interactive plotting with plotly (if available)
try:
import plotly.graph_objects as go
from igraph.drawing.plotly import plot as plot_plotly
# Create interactive plot
fig = plot_plotly(g,
layout=layout,
vertex_size=vertex_degrees,
vertex_color=communities.membership,
vertex_text=[f"Vertex {i}" for i in range(g.vcount())],
edge_width=1)
# Customize interactivity
fig.update_layout(
title="Interactive Network Visualization",
showlegend=False,
hovermode='closest',
width=800,
height=600
)
# Display in notebook or save as HTML
fig.show()
fig.write_html("interactive_network.html")
except ImportError:
print("Plotly not available, using Cairo backend")
ig.plot(g, layout=layout, bbox=(800, 600))Use matplotlib backend for integration with scientific plotting workflows.
# Matplotlib-specific functionality
class MatplotlibGraphDrawer:
def __init__(self, context):
"""Initialize matplotlib drawer with axis context."""
def draw(self, graph, **kwargs):
"""Draw graph on matplotlib axis."""Usage Examples:
# Matplotlib integration
try:
import matplotlib.pyplot as plt
from igraph.drawing.matplotlib import MatplotlibGraphDrawer
# Create subplot layout
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
# Plot original graph
ax1.set_title("Original Network")
drawer1 = MatplotlibGraphDrawer(ax1)
drawer1.draw(g,
layout=layout,
vertex_size=vertex_degrees,
vertex_color=communities.membership)
# Plot simplified version
g_simple = g.simplify()
ax2.set_title("Simplified Network")
drawer2 = MatplotlibGraphDrawer(ax2)
drawer2.draw(g_simple,
layout=g_simple.layout_fruchterman_reingold(),
vertex_size=20,
vertex_color="lightblue")
plt.tight_layout()
plt.savefig("network_comparison.png", dpi=300, bbox_inches='tight')
plt.show()
except ImportError:
print("Matplotlib not available")Custom visualization types for specific analysis needs.
Usage Examples:
# Adjacency matrix visualization
adj_matrix = g.get_adjacency_sparse()
ig.plot(adj_matrix, "adjacency_matrix.png")
# Community structure visualization
def plot_community_structure(graph, communities):
"""Enhanced community visualization."""
# Create color map for communities
n_communities = len(communities)
colors = ig.RainbowPalette(n_communities)
# Size vertices by within-community degree
within_degrees = []
for v in graph.vs:
v_community = communities.membership[v.index]
community_vertices = [i for i, c in enumerate(communities.membership) if c == v_community]
subgraph = graph.subgraph(community_vertices)
within_degrees.append(subgraph.degree()[community_vertices.index(v.index)])
return ig.plot(graph,
layout=graph.layout_fruchterman_reingold(),
vertex_color=[colors.get(c) for c in communities.membership],
vertex_size=[5 + d*3 for d in within_degrees],
vertex_frame_color="black",
vertex_frame_width=1,
edge_width=0.5,
edge_color="gray",
bbox=(1000, 800),
margin=50)
# Edge bundling visualization
def plot_with_edge_bundling(graph, layout, bundle_strength=0.8):
"""Simulate edge bundling effect."""
# Calculate edge curvature based on community crossing
communities = graph.community_leiden()
edge_curved = []
for edge in graph.es:
source_comm = communities.membership[edge.source]
target_comm = communities.membership[edge.target]
# More curvature for inter-community edges
curvature = bundle_strength if source_comm != target_comm else 0.1
edge_curved.append(curvature)
return ig.plot(graph,
layout=layout,
vertex_color=communities.membership,
edge_curved=edge_curved,
edge_color=["red" if c > 0.5 else "lightgray" for c in edge_curved],
bbox=(800, 600))
# Multi-layer network visualization
def plot_multilayer(graphs, layouts=None, titles=None):
"""Plot multiple related graphs."""
n_graphs = len(graphs)
if layouts is None:
layouts = [g.layout_fruchterman_reingold() for g in graphs]
if titles is None:
titles = [f"Layer {i+1}" for i in range(n_graphs)]
# Create grid layout for multiple plots
import math
cols = math.ceil(math.sqrt(n_graphs))
rows = math.ceil(n_graphs / cols)
for i, (graph, layout, title) in enumerate(zip(graphs, layouts, titles)):
ig.plot(graph,
f"layer_{i+1}.png",
layout=layout,
vertex_size=15,
vertex_color="lightblue",
bbox=(400, 400),
margin=30)
# Usage
plot_community_structure(g, communities)
plot_with_edge_bundling(g, layout)Install with Tessl CLI
npx tessl i tessl/pypi-igraph