NetworkX is a Python library for studying graphs and networks. NetworkX is free software released under the BSD-new license.
History NetworkX began development in 2002 by Aric A. Hagberg, Daniel A. Schult, and Pieter J. Swart.Aric A. Hagberg, Daniel A. Schult, Pieter J. Swart, Exploring Network Structure, Dynamics, and Function using NetworkX , Proceedings of the 7th Python in Science conference (SciPy 2008), G. Varoquaux, T. Vaught, J. Millman (Eds.), pp. 11–15. It is supported by the National Nuclear Security Administration of the U.S. Department of Energy at Los Alamos National Laboratory.
The package was crafted with the aim of creating tools to analyze data and intervention strategies for controlling the epidemic spread of disease, while also exploring the structure and dynamics of more general social, biological, and infrastructural systems.
Inspired by Guido van Rossum's 1998 essay on Python graph representation, NetworkX made its public debut at the 2004 SciPy annual conference. In April 2005, NetworkX was made available as open source software.
Several Python packages focusing on graph theory, including igraph, graph-tool, and numerous others, are available. As of April 2024, NetworkX had over 50 million downloads, surpassing the download count of the second most popular package, igraph, by more than 50-fold. This substantial adoption rate could potentially be attributed to NetworkX's early release and its continued evolution within the SciPy ecosystem.
In 2008, SageMath, an open source mathematics system, incorporated NetworkX into its package and added support for more graphing algorithms and functions.
+ Major NetworkX Releases Version Release date Major Changes 0.22 Topological sorting for testing directed acyclic graphs (DAGs). Integration of Dijkstra's algorithm for finding shortest paths in weighted graphs. 0.99 Default graph type transitioned to a weighted graph. MultiGraph, MultiDiGraph, LabeledGraph, and LabeledDiGraph introduced. 1.0 Addition of difference and intersection operators. Implementation of the A* algorithm for optimized pathfinding.
Incorporation of PageRank, HITS, and [eigenvector] centrality algorithms for network analysis.
Integration of Kruskal's algorithm for constructing minimum spanning trees. 2.0 Significant revisions to the methods within the MultiGraph and DiGraph classes. Overhaul of documentation system. Various user quality of life changes. 3.0 Improved integrations to SciPy ecosystem packages. Added new plugin feature to allow users to use different backends (GraphBLAS, CuGraph) for computation.
Features Classes for graphs and digraphs. Conversion of graphs to and from several formats. Ability to construct random graphs or construct them incrementally. Ability to find subgraphs, cliques, k-cores. Explore adjacency, degree, diameter, radius, center, betweenness, etc. Draw networks in 2D and 3D.
Supported graph types
Overview Graphs, in this context, represent collections of vertices (nodes) and edges (connections) between them. NetworkX provides support for several types of graphs, each suited for different applications and scenarios.
Directed graphs (DiGraph) Directed graphs, or DiGraphs, consist of nodes connected by directed edges. In a directed graph, edges have a direction indicating the flow or relationship between nodes.
Undirected graphs (Graph) Undirected graphs, simply referred to as graphs in NetworkX, are graphs where edges have no inherent direction. The connections between nodes are symmetrical, meaning if node A is connected to node B, then node B is also connected to node A.
MultiGraphs MultiGraphs allow multiple edges between the same pair of nodes. In other words, MultiGraphs permit parallel edges, where more than one edge can exist between two nodes.
MultiDiGraphs MultiDiGraphs are directed graphs that allow multiple directed edges between the same pair of nodes. Similar to MultiGraphs, MultiDiGraphs enable the modeling of scenarios where multiple directed relationships exist between nodes.
Challenges in visualization While NetworkX provides powerful tools for graph creation and analysis, producing visualizations of complex graphs can be challenging. Visualizing large or densely connected graphs may require specialized techniques and external libraries beyond the capabilities of NetworkX alone.
Graph layouts NetworkX provides various layout algorithms for visualizing graphs in two-dimensional space. These layout algorithms determine the positions of nodes and edges in a graph visualization, aiming to reveal its structure and relationships effectively.
Spring layout The Spring Layout in NetworkX is a popular way to visualize graphs using a force-directed algorithm. It's based on the Fruchterman-Reingold model, which works like a virtual physics simulation. Each node in your graph is a charged particle that repels other nodes, while the edges act like springs that pull connected nodes closer together. This balance creates a layout where the graph naturally spreads out into an informative shape.
As the algorithm runs, it tries to reduce the overall "energy" of the system by adjusting the positions of the nodes step by step. The result often highlights patterns in the graph—like clusters or groups of nodes that are tightly connected. It works best for small to medium-sized graphs, where clarity and appearance are important.
You can create this layout in NetworkX using the spring_layout() function, found in networkx.drawing.layout. The function gives you a few options to customize the layout, you can control the distance between nodes with the k parameter or decide how many iterations the simulation should run. It lets you lay out the graph in more than two dimensions by setting the dim parameter.
G = nx.path_graph(4) pos = nx.spring_layout(G) nx.draw(G, pos, with_labels=True)This layout method is used for interactive and exploratory visualizations. The spring layout often reveals the structure of the graph in a intuitive and readable way
Spectral layout The Spectral layout is based on the spectral properties of the graph's adjacency matrix. It uses the eigenvalues and eigenvectors of the adjacency matrix to position nodes in a low-dimensional space. Spectral layout tends to emphasize the global structure of the graph, making it useful for identifying clusters and communities.
How the spectral layout work Source:
Construct the Laplacian matrix of the graph. A Laplacian matrix L of a graph is defined as , where is the degree matrix (a diagonal matrix where is the degree of vertex i) and A is the adjacency matrix.
For a graph with n vertices, the adjacency matrix A is an n × n matrix where if there is an edge between vertex i and vertex i and otherwise.
The Laplacian matrix has eigenvalues and corresponding eigenvectors that encode the graph's structural properties.
Compute the eigenvectors corresponding to the smallest non-zero eigenvalues. Use these eigenvectors as coordinate values for positioning vertices. X-coordinates come from the second eigenvector (associated with the second-smallest eigenvalue), and Y-coordinates come from the third eigenvector. Scale and center the resulting layout as needed.
Why it reveals the network's structure Nodes in dense clusters have similar eigenvector entries, causing them to group spatially. The Fiedler vector (second eigenvector) minimizes the ratio cut, separating the graph into clusters with minimal interconnections.
In the plot above, we observe that the spectral layout helps capture the global and communal structures embedded in the graph. Comparing both layouts, we see that the spectral layout keeps nodes belonging to the same community closely packed, thereby capturing communities more easily as compared to the spring layout.
Codes for implementing the plot import numpy as np import matplotlib.pyplot as plt import networkx as nx
# Generate a graph with overlapping nodes in spectral layout G = nx.karate_club_graph() L = nx.laplacian_matrix(G).todense()
# Compute eigenvectors of L for spectral layout eigenvals, eigenvecs = np.linalg.eigh(L) fiedler_vector = eigenvecs[:, 1] # Second smallest eigenvector eigenvec2 = eigenvecs[:, 2] # Third smallest eigenvector
# Create spectral layout (2D: use Fiedler vector for x-coord, zeros for y-coord) pos_spectral = {node: (fiedler_vector[i]+ np.random.normal(0, 0.01), eigenvec2[i]+ np.random.normal(0, 0.1)) for i, node in enumerate(G.nodes())}
# Define layouts to compare layouts = { "Spring Layout": nx.spring_layout(G, seed=42), "Spectral Layout": pos_spectral }
# Plot all layouts plt.figure(figsize=(15, 8)) for i, (title, pos) in enumerate(layouts.items(), 1): plt.subplot(1, 2, i) nx.draw(G, pos, with_labels=True, node_color='skyblue', node_size=800, font_size=10) plt.title(title) plt.tight_layout() plt.savefig('Spec_layout.png') plt.show()
Circular layout
The Circular layout arranges nodes evenly around a circle, with edges drawn as straight lines connecting them. This layout is particularly suitable for visualizing cyclic or symmetric graphs, where the arrangement of nodes along the circle reflects the underlying topology of the graph.
Shell layout
The Shell layout organizes nodes into concentric circles or shells based on their distance from a specified center. Nodes within the same shell have the same distance from the center, while edges are drawn radially between nodes in adjacent shells. Shell layout is often used for visualizing hierarchical or tree structures.
Sample code # simple shell‐layout example G = nx.balanced_tree(2, 2) shells = [, [1, 2], [3, 4, 5, 6]] pos = nx.shell_layout(G, nlist=shells) nx.draw(G, pos, with_labels=True)
Kamada–Kawai layout
The Kamada–Kawai layout algorithm positions nodes based on their pairwise distances, aiming to minimize the total energy of the system. It takes into account both the graph's topology and edge lengths, resulting in a layout that emphasizes geometric accuracy and readability.
Random Layout
Random layout assigns each node a random position inside the unit square (or specified box). It's trivial and fast—O(n)—but gives no information about graph structure. Use it as a baseline to compare against more meaningful layouts, or when you just need an initial seeding for iterative algorithms. It's also handy for stress-testing your rendering pipeline.
Planar Layout Planar layout attempts to compute an embedding for planar graphs (graphs with no edge crossings) using graph combinatorial embedding. If the graph isn't planar, it raises an exception. Planar embeddings exactly preserve the topology of planar networks—useful for circuit schematics, maps, or any truly planar structure. When it works, edges don't cross, giving a clean representation. It's linear‐time but only applicable to planar graphs.
Fruchterman–Reingold Layout Although "spring layout" and "Fruchterman–Reingold" are often used interchangeably, NetworkX exposes both via spring_layout and fruchterman_reingold_layout. Internally they share the same physics-based algorithm. You can tweak attraction/repulsion constants, number of iterations, and temperature schedules. It produces an "organic" network view that highlights dense subgraphs. Use it when you want a familiar force-directed aesthetic with customizable parameters.
Spiral Layout
Spiral layout places nodes along an outward spiral, one after another in node order. It's deterministic and extremely fast—useful for very large graphs where more expensive layouts would be too slow. Although it doesn't use graph connectivity, you can impose ordering to reveal sequences or ranking. Because the spiral arms grow apart as they wind out, it can reduce overlap compared to a pure line or circle. It's primarily a novelty, but useful for displaying long chains or temporal orderings.
Bipartite Layout