# Table of Contents - [Reference — NetworkX 3.4.2 documentation](#reference-networkx-3-4-2-documentation) - [Install — NetworkX 3.4.2 documentation](#install-networkx-3-4-2-documentation) - [Software for Complex Networks — NetworkX 3.4.2 documentation](#software-for-complex-networks-networkx-3-4-2-documentation) - [Backends — NetworkX 3.4.2 documentation](#backends-networkx-3-4-2-documentation) - [Tutorial — NetworkX 3.4.2 documentation](#tutorial-networkx-3-4-2-documentation) - [Gallery — NetworkX 3.4.2 documentation](#gallery-networkx-3-4-2-documentation) - [Developer — NetworkX 3.4.2 documentation](#developer-networkx-3-4-2-documentation) - [Releases — NetworkX 3.4.2 documentation](#releases-networkx-3-4-2-documentation) - [Welcome to nx-guides! — NetworkX Notebooks](#welcome-to-nx-guides-networkx-notebooks) - [NetworkX — NetworkX documentation](#networkx-networkx-documentation) - [Introduction — NetworkX 3.4.2 documentation](#introduction-networkx-3-4-2-documentation) - [Algorithms — NetworkX 3.4.2 documentation](#algorithms-networkx-3-4-2-documentation) - [Graph types — NetworkX 3.4.2 documentation](#graph-types-networkx-3-4-2-documentation) - [Functions — NetworkX 3.4.2 documentation](#functions-networkx-3-4-2-documentation) - [Linear algebra — NetworkX 3.4.2 documentation](#linear-algebra-networkx-3-4-2-documentation) - [Geospatial Examples Description — NetworkX 3.4.2 documentation](#geospatial-examples-description-networkx-3-4-2-documentation) - [Graph generators — NetworkX 3.4.2 documentation](#graph-generators-networkx-3-4-2-documentation) - [Reading and writing graphs — NetworkX 3.4.2 documentation](#reading-and-writing-graphs-networkx-3-4-2-documentation) - [Converting to and from other data formats — NetworkX 3.4.2 documentation](#converting-to-and-from-other-data-formats-networkx-3-4-2-documentation) - [Backends — NetworkX 3.4.2 documentation](#backends-networkx-3-4-2-documentation) - [Relabeling nodes — NetworkX 3.4.2 documentation](#relabeling-nodes-networkx-3-4-2-documentation) - [Randomness — NetworkX 3.4.2 documentation](#randomness-networkx-3-4-2-documentation) - [Welcome to nx-guides! — NetworkX Notebooks](#welcome-to-nx-guides-networkx-notebooks) - [Utilities — NetworkX 3.4.2 documentation](#utilities-networkx-3-4-2-documentation) - [Glossary — NetworkX 3.4.2 documentation](#glossary-networkx-3-4-2-documentation) - [Exceptions — NetworkX 3.4.2 documentation](#exceptions-networkx-3-4-2-documentation) - [Drawing — NetworkX 3.4.2 documentation](#drawing-networkx-3-4-2-documentation) - [Approximations and Heuristics — NetworkX 3.4.2 documentation](#approximations-and-heuristics-networkx-3-4-2-documentation) - [Configs — NetworkX 3.4.2 documentation](#configs-networkx-3-4-2-documentation) - [Assortativity — NetworkX 3.4.2 documentation](#assortativity-networkx-3-4-2-documentation) - [Asteroidal — NetworkX 3.4.2 documentation](#asteroidal-networkx-3-4-2-documentation) - [Boundary — NetworkX 3.4.2 documentation](#boundary-networkx-3-4-2-documentation) - [Broadcasting — NetworkX 3.4.2 documentation](#broadcasting-networkx-3-4-2-documentation) - [Bipartite — NetworkX 3.4.2 documentation](#bipartite-networkx-3-4-2-documentation) - [Bridges — NetworkX 3.4.2 documentation](#bridges-networkx-3-4-2-documentation) - [Chains — NetworkX 3.4.2 documentation](#chains-networkx-3-4-2-documentation) - [Centrality — NetworkX 3.4.2 documentation](#centrality-networkx-3-4-2-documentation) - [Clustering — NetworkX 3.4.2 documentation](#clustering-networkx-3-4-2-documentation) - [Chordal — NetworkX 3.4.2 documentation](#chordal-networkx-3-4-2-documentation) - [Coloring — NetworkX 3.4.2 documentation](#coloring-networkx-3-4-2-documentation) - [Clique — NetworkX 3.4.2 documentation](#clique-networkx-3-4-2-documentation) - [Communicability — NetworkX 3.4.2 documentation](#communicability-networkx-3-4-2-documentation) - [Communities — NetworkX 3.4.2 documentation](#communities-networkx-3-4-2-documentation) - [Components — NetworkX 3.4.2 documentation](#components-networkx-3-4-2-documentation) - [Connectivity — NetworkX 3.4.2 documentation](#connectivity-networkx-3-4-2-documentation) - [Cores — NetworkX 3.4.2 documentation](#cores-networkx-3-4-2-documentation) - [Covering — NetworkX 3.4.2 documentation](#covering-networkx-3-4-2-documentation) - [Cycles — NetworkX 3.4.2 documentation](#cycles-networkx-3-4-2-documentation) - [Cuts — NetworkX 3.4.2 documentation](#cuts-networkx-3-4-2-documentation) - [Distance-Regular Graphs — NetworkX 3.4.2 documentation](#distance-regular-graphs-networkx-3-4-2-documentation) - [D-Separation — NetworkX 3.4.2 documentation](#d-separation-networkx-3-4-2-documentation) - [Dominance — NetworkX 3.4.2 documentation](#dominance-networkx-3-4-2-documentation) - [Directed Acyclic Graphs — NetworkX 3.4.2 documentation](#directed-acyclic-graphs-networkx-3-4-2-documentation) - [Dominating Sets — NetworkX 3.4.2 documentation](#dominating-sets-networkx-3-4-2-documentation) - [Distance Measures — NetworkX 3.4.2 documentation](#distance-measures-networkx-3-4-2-documentation) - [Efficiency — NetworkX 3.4.2 documentation](#efficiency-networkx-3-4-2-documentation) - [Eulerian — NetworkX 3.4.2 documentation](#eulerian-networkx-3-4-2-documentation) - [Flows — NetworkX 3.4.2 documentation](#flows-networkx-3-4-2-documentation) - [Graphical degree sequence — NetworkX 3.4.2 documentation](#graphical-degree-sequence-networkx-3-4-2-documentation) - [Graph Hashing — NetworkX 3.4.2 documentation](#graph-hashing-networkx-3-4-2-documentation) - [Hierarchy — NetworkX 3.4.2 documentation](#hierarchy-networkx-3-4-2-documentation) - [Hybrid — NetworkX 3.4.2 documentation](#hybrid-networkx-3-4-2-documentation) - [Isolates — NetworkX 3.4.2 documentation](#isolates-networkx-3-4-2-documentation) - [Link Analysis — NetworkX 3.4.2 documentation](#link-analysis-networkx-3-4-2-documentation) - [Isomorphism — NetworkX 3.4.2 documentation](#isomorphism-networkx-3-4-2-documentation) - [Lowest Common Ancestor — NetworkX 3.4.2 documentation](#lowest-common-ancestor-networkx-3-4-2-documentation) - [Link Prediction — NetworkX 3.4.2 documentation](#link-prediction-networkx-3-4-2-documentation) - [Matching — NetworkX 3.4.2 documentation](#matching-networkx-3-4-2-documentation) - [Minors — NetworkX 3.4.2 documentation](#minors-networkx-3-4-2-documentation) - [Maximal independent set — NetworkX 3.4.2 documentation](#maximal-independent-set-networkx-3-4-2-documentation) - [Moral — NetworkX 3.4.2 documentation](#moral-networkx-3-4-2-documentation) - [Operators — NetworkX 3.4.2 documentation](#operators-networkx-3-4-2-documentation) - [non-randomness — NetworkX 3.4.2 documentation](#non-randomness-networkx-3-4-2-documentation) - [Node Classification — NetworkX 3.4.2 documentation](#node-classification-networkx-3-4-2-documentation) - [Planar Drawing — NetworkX 3.4.2 documentation](#planar-drawing-networkx-3-4-2-documentation) - [Planarity — NetworkX 3.4.2 documentation](#planarity-networkx-3-4-2-documentation) - [Graph Polynomials — NetworkX 3.4.2 documentation](#graph-polynomials-networkx-3-4-2-documentation) - [Regular — NetworkX 3.4.2 documentation](#regular-networkx-3-4-2-documentation) - [Reciprocity — NetworkX 3.4.2 documentation](#reciprocity-networkx-3-4-2-documentation) - [Rich Club — NetworkX 3.4.2 documentation](#rich-club-networkx-3-4-2-documentation) - [Shortest Paths — NetworkX 3.4.2 documentation](#shortest-paths-networkx-3-4-2-documentation) - [Similarity Measures — NetworkX 3.4.2 documentation](#similarity-measures-networkx-3-4-2-documentation) - [Simple Paths — NetworkX 3.4.2 documentation](#simple-paths-networkx-3-4-2-documentation) - [Small-world — NetworkX 3.4.2 documentation](#small-world-networkx-3-4-2-documentation) - [s metric — NetworkX 3.4.2 documentation](#s-metric-networkx-3-4-2-documentation) - [Sparsifiers — NetworkX 3.4.2 documentation](#sparsifiers-networkx-3-4-2-documentation) - [Summarization — NetworkX 3.4.2 documentation](#summarization-networkx-3-4-2-documentation) - [Structural holes — NetworkX 3.4.2 documentation](#structural-holes-networkx-3-4-2-documentation) - [Swap — NetworkX 3.4.2 documentation](#swap-networkx-3-4-2-documentation) - [Time dependent — NetworkX 3.4.2 documentation](#time-dependent-networkx-3-4-2-documentation) - [Threshold Graphs — NetworkX 3.4.2 documentation](#threshold-graphs-networkx-3-4-2-documentation) - [Tournament — NetworkX 3.4.2 documentation](#tournament-networkx-3-4-2-documentation) - [Traversal — NetworkX 3.4.2 documentation](#traversal-networkx-3-4-2-documentation) - [Triads — NetworkX 3.4.2 documentation](#triads-networkx-3-4-2-documentation) - [Tree — NetworkX 3.4.2 documentation](#tree-networkx-3-4-2-documentation) - [Vitality — NetworkX 3.4.2 documentation](#vitality-networkx-3-4-2-documentation) - [Voronoi cells — NetworkX 3.4.2 documentation](#voronoi-cells-networkx-3-4-2-documentation) - [Walks — NetworkX 3.4.2 documentation](#walks-networkx-3-4-2-documentation) - [Adjacency List — NetworkX 3.4.2 documentation](#adjacency-list-networkx-3-4-2-documentation) - [Wiener Index — NetworkX 3.4.2 documentation](#wiener-index-networkx-3-4-2-documentation) - [DOT — NetworkX 3.4.2 documentation](#dot-networkx-3-4-2-documentation) - [Multiline Adjacency List — NetworkX 3.4.2 documentation](#multiline-adjacency-list-networkx-3-4-2-documentation) - [Edge List — NetworkX 3.4.2 documentation](#edge-list-networkx-3-4-2-documentation) - [GEXF — NetworkX 3.4.2 documentation](#gexf-networkx-3-4-2-documentation) - [GML — NetworkX 3.4.2 documentation](#gml-networkx-3-4-2-documentation) - [GraphML — NetworkX 3.4.2 documentation](#graphml-networkx-3-4-2-documentation) - [JSON — NetworkX 3.4.2 documentation](#json-networkx-3-4-2-documentation) - [LEDA — NetworkX 3.4.2 documentation](#leda-networkx-3-4-2-documentation) - [SparseGraph6 — NetworkX 3.4.2 documentation](#sparsegraph6-networkx-3-4-2-documentation) - [Pajek — NetworkX 3.4.2 documentation](#pajek-networkx-3-4-2-documentation) - [Matrix Market — NetworkX 3.4.2 documentation](#matrix-market-networkx-3-4-2-documentation) - [Network Text — NetworkX 3.4.2 documentation](#network-text-networkx-3-4-2-documentation) - [_dispatchable — NetworkX 3.4.2 documentation](#-dispatchable-networkx-3-4-2-documentation) - [Code of Conduct — NetworkX 3.4.2 documentation](#code-of-conduct-networkx-3-4-2-documentation) - [About Us — NetworkX 3.4.2 documentation](#about-us-networkx-3-4-2-documentation) - [Mission and Values — NetworkX 3.4.2 documentation](#mission-and-values-networkx-3-4-2-documentation) - [Algorithms — NetworkX Notebooks](#algorithms-networkx-notebooks) - [Contributor Guide — NetworkX 3.4.2 documentation](#contributor-guide-networkx-3-4-2-documentation) - [Mentored Projects — NetworkX 3.4.2 documentation](#mentored-projects-networkx-3-4-2-documentation) - [New Contributor FAQ — NetworkX 3.4.2 documentation](#new-contributor-faq-networkx-3-4-2-documentation) - [Core Developer Guide — NetworkX 3.4.2 documentation](#core-developer-guide-networkx-3-4-2-documentation) - [Node Assortativity Coefficients and Correlation Measures — NetworkX Notebooks](#node-assortativity-coefficients-and-correlation-measures-networkx-notebooks) - [Software for Complex Networks — NetworkX 3.4.2 documentation](#software-for-complex-networks-networkx-3-4-2-documentation) - [NetworkX 3.4.2 — NetworkX 3.4.2 documentation](#networkx-3-4-2-networkx-3-4-2-documentation) - [Directed Acyclic Graphs & Topological Sort — NetworkX Notebooks](#directed-acyclic-graphs-topological-sort-networkx-notebooks) - [NetworkX 3.4.1 — NetworkX 3.4.2 documentation](#networkx-3-4-1-networkx-3-4-2-documentation) - [Release Process — NetworkX 3.4.2 documentation](#release-process-networkx-3-4-2-documentation) - [Page not found · GitHub Pages](#page-not-found-github-pages) - [Lowest Common Ancestor — NetworkX Notebooks](#lowest-common-ancestor-networkx-notebooks) - [NetworkX 3.4 — NetworkX 3.4.2 documentation](#networkx-3-4-networkx-3-4-2-documentation) - [Dinitz’s Algorithm and Applications — NetworkX Notebooks](#dinitz-s-algorithm-and-applications-networkx-notebooks) - [Software for Complex Networks — NetworkX 3.5rc0.dev0 documentation](#software-for-complex-networks-networkx-3-5rc0-dev0-documentation) - [Roadmap — NetworkX 3.4.2 documentation](#roadmap-networkx-3-4-2-documentation) - [Deprecations — NetworkX 3.4.2 documentation](#deprecations-networkx-3-4-2-documentation) - [NetworkX 3.3 — NetworkX 3.4.2 documentation](#networkx-3-3-networkx-3-4-2-documentation) - [Euler’s Algorithm — NetworkX Notebooks](#euler-s-algorithm-networkx-notebooks) - [NXEPs — NetworkX 3.4.2 documentation](#nxeps-networkx-3-4-2-documentation) - [NetworkX 3.2.1 — NetworkX 3.4.2 documentation](#networkx-3-2-1-networkx-3-4-2-documentation) - [Isomorphism - How to find if two graphs are similar? — NetworkX Notebooks](#isomorphism-how-to-find-if-two-graphs-are-similar-networkx-notebooks) - [Graph Generators — NetworkX Notebooks](#graph-generators-networkx-notebooks) - [NetworkX 3.1 — NetworkX 3.4.2 documentation](#networkx-3-1-networkx-3-4-2-documentation) - [Geometric Generator Models — NetworkX Notebooks](#geometric-generator-models-networkx-notebooks) - [NetworkX 3.2 — NetworkX 3.4.2 documentation](#networkx-3-2-networkx-3-4-2-documentation) - [NetworkX 3.0 — NetworkX 3.4.2 documentation](#networkx-3-0-networkx-3-4-2-documentation) - [NetworkX 2.8.8 — NetworkX 3.4.2 documentation](#networkx-2-8-8-networkx-3-4-2-documentation) - [Sudoku and Graph Coloring — NetworkX Notebooks](#sudoku-and-graph-coloring-networkx-notebooks) - [NXEP 0 — Purpose and Process — NetworkX 3.4.2 documentation](#nxep-0-purpose-and-process-networkx-3-4-2-documentation) - [Contributors Guide — NetworkX Notebooks](#contributors-guide-networkx-notebooks) - [NXEP 1 — Governance and Decision Making — NetworkX 3.4.2 documentation](#nxep-1-governance-and-decision-making-networkx-3-4-2-documentation) - [NetworkX 2.8.6 — NetworkX 3.4.2 documentation](#networkx-2-8-6-networkx-3-4-2-documentation) - [Unknown](#unknown) - [NXEP 2 — API design of view slices — NetworkX 3.4.2 documentation](#nxep-2-api-design-of-view-slices-networkx-3-4-2-documentation) - [Facebook Network Analysis — NetworkX Notebooks](#facebook-network-analysis-networkx-notebooks) - [NetworkX 2.8.7 — NetworkX 3.4.2 documentation](#networkx-2-8-7-networkx-3-4-2-documentation) - [NetworkX 2.8.5 — NetworkX 3.4.2 documentation](#networkx-2-8-5-networkx-3-4-2-documentation) - [NXEP 4 — Default random interface — NetworkX 3.4.2 documentation](#nxep-4-default-random-interface-networkx-3-4-2-documentation) --- # Reference — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Reference[#](#reference "Link to this heading") ================================================ > Release: > > 3.4.2 > > Date: > > Oct 21, 2024 * [Introduction](introduction.html) * [NetworkX Basics](introduction.html#networkx-basics) * [Graphs](introduction.html#graphs) * [Graph Creation](introduction.html#graph-creation) * [Graph Reporting](introduction.html#graph-reporting) * [Algorithms](introduction.html#algorithms) * [Drawing](introduction.html#drawing) * [Data Structure](introduction.html#data-structure) * [Graph types](classes/index.html) * [Which graph class should I use?](classes/index.html#which-graph-class-should-i-use) * [Basic graph types](classes/index.html#basic-graph-types) * [Graph Views](classes/index.html#module-networkx.classes.graphviews) * [Core Views](classes/index.html#module-networkx.classes.coreviews) * [Filters](classes/index.html#filters) * [Algorithms](algorithms/index.html) * [Approximations and Heuristics](algorithms/approximation.html) * [Assortativity](algorithms/assortativity.html) * [Asteroidal](algorithms/asteroidal.html) * [Bipartite](algorithms/bipartite.html) * [Boundary](algorithms/boundary.html) * [Bridges](algorithms/bridges.html) * [Broadcasting](algorithms/broadcasting.html) * [Centrality](algorithms/centrality.html) * [Chains](algorithms/chains.html) * [Chordal](algorithms/chordal.html) * [Clique](algorithms/clique.html) * [Clustering](algorithms/clustering.html) * [Coloring](algorithms/coloring.html) * [Communicability](algorithms/communicability_alg.html) * [Communities](algorithms/community.html) * [Components](algorithms/component.html) * [Connectivity](algorithms/connectivity.html) * [Cores](algorithms/core.html) * [Covering](algorithms/covering.html) * [Cycles](algorithms/cycles.html) * [Cuts](algorithms/cuts.html) * [D-Separation](algorithms/d_separation.html) * [Directed Acyclic Graphs](algorithms/dag.html) * [Distance Measures](algorithms/distance_measures.html) * [Distance-Regular Graphs](algorithms/distance_regular.html) * [Dominance](algorithms/dominance.html) * [Dominating Sets](algorithms/dominating.html) * [Efficiency](algorithms/efficiency_measures.html) * [Eulerian](algorithms/euler.html) * [Flows](algorithms/flow.html) * [Graph Hashing](algorithms/graph_hashing.html) * [Graphical degree sequence](algorithms/graphical.html) * [Hierarchy](algorithms/hierarchy.html) * [Hybrid](algorithms/hybrid.html) * [Isolates](algorithms/isolates.html) * [Isomorphism](algorithms/isomorphism.html) * [Link Analysis](algorithms/link_analysis.html) * [Link Prediction](algorithms/link_prediction.html) * [Lowest Common Ancestor](algorithms/lowest_common_ancestors.html) * [Matching](algorithms/matching.html) * [Minors](algorithms/minors.html) * [Maximal independent set](algorithms/mis.html) * [non-randomness](algorithms/non_randomness.html) * [Moral](algorithms/moral.html) * [Node Classification](algorithms/node_classification.html) * [Operators](algorithms/operators.html) * [Planarity](algorithms/planarity.html) * [Planar Drawing](algorithms/planar_drawing.html) * [Graph Polynomials](algorithms/polynomials.html) * [Reciprocity](algorithms/reciprocity.html) * [Regular](algorithms/regular.html) * [Rich Club](algorithms/rich_club.html) * [Shortest Paths](algorithms/shortest_paths.html) * [Similarity Measures](algorithms/similarity.html) * [Simple Paths](algorithms/simple_paths.html) * [Small-world](algorithms/smallworld.html) * [s metric](algorithms/smetric.html) * [Sparsifiers](algorithms/sparsifiers.html) * [Structural holes](algorithms/structuralholes.html) * [Summarization](algorithms/summarization.html) * [Swap](algorithms/swap.html) * [Threshold Graphs](algorithms/threshold.html) * [Time dependent](algorithms/time_dependent.html) * [Tournament](algorithms/tournament.html) * [Traversal](algorithms/traversal.html) * [Tree](algorithms/tree.html) * [Triads](algorithms/triads.html) * [Vitality](algorithms/vitality.html) * [Voronoi cells](algorithms/voronoi.html) * [Walks](algorithms/walks.html) * [Wiener Index](algorithms/wiener.html) * [Functions](functions.html) * [Graph](functions.html#graph) * [Nodes](functions.html#nodes) * [Edges](functions.html#edges) * [Self loops](functions.html#self-loops) * [Attributes](functions.html#attributes) * [Paths](functions.html#paths) * [Freezing graph structure](functions.html#freezing-graph-structure) * [Graph generators](generators.html) * [Atlas](generators.html#module-networkx.generators.atlas) * [Classic](generators.html#module-networkx.generators.classic) * [Expanders](generators.html#module-networkx.generators.expanders) * [Lattice](generators.html#module-networkx.generators.lattice) * [Small](generators.html#module-networkx.generators.small) * [Random Graphs](generators.html#module-networkx.generators.random_graphs) * [Duplication Divergence](generators.html#module-networkx.generators.duplication) * [Degree Sequence](generators.html#module-networkx.generators.degree_seq) * [Random Clustered](generators.html#module-networkx.generators.random_clustered) * [Directed](generators.html#module-networkx.generators.directed) * [Geometric](generators.html#module-networkx.generators.geometric) * [Line Graph](generators.html#module-networkx.generators.line) * [Ego Graph](generators.html#module-networkx.generators.ego) * [Stochastic](generators.html#module-networkx.generators.stochastic) * [AS graph](generators.html#module-networkx.generators.internet_as_graphs) * [Intersection](generators.html#module-networkx.generators.intersection) * [Social Networks](generators.html#module-networkx.generators.social) * [Community](generators.html#module-networkx.generators.community) * [Spectral](generators.html#module-networkx.generators.spectral_graph_forge) * [Trees](generators.html#module-networkx.generators.trees) * [Non Isomorphic Trees](generators.html#module-networkx.generators.nonisomorphic_trees) * [Triads](generators.html#module-networkx.generators.triads) * [Joint Degree Sequence](generators.html#module-networkx.generators.joint_degree_seq) * [Mycielski](generators.html#module-networkx.generators.mycielski) * [Harary Graph](generators.html#module-networkx.generators.harary_graph) * [Cographs](generators.html#module-networkx.generators.cographs) * [Interval Graph](generators.html#module-networkx.generators.interval_graph) * [Sudoku](generators.html#module-networkx.generators.sudoku) * [Time Series](generators.html#module-networkx.generators.time_series) * [Linear algebra](linalg.html) * [Graph Matrix](linalg.html#module-networkx.linalg.graphmatrix) * [Laplacian Matrix](linalg.html#module-networkx.linalg.laplacianmatrix) * [Bethe Hessian Matrix](linalg.html#module-networkx.linalg.bethehessianmatrix) * [Algebraic Connectivity](linalg.html#module-networkx.linalg.algebraicconnectivity) * [Attribute Matrices](linalg.html#module-networkx.linalg.attrmatrix) * [Modularity Matrices](linalg.html#module-networkx.linalg.modularitymatrix) * [Spectrum](linalg.html#module-networkx.linalg.spectrum) * [Converting to and from other data formats](convert.html) * [To NetworkX Graph](convert.html#module-networkx.convert) * [Dictionaries](convert.html#dictionaries) * [Lists](convert.html#lists) * [Numpy](convert.html#module-networkx.convert_matrix) * [Scipy](convert.html#scipy) * [Pandas](convert.html#pandas) * [Relabeling nodes](relabel.html) * [Relabeling](relabel.html#module-networkx.relabel) * [Reading and writing graphs](readwrite/index.html) * [Adjacency List](readwrite/adjlist.html) * [Multiline Adjacency List](readwrite/multiline_adjlist.html) * [DOT](readwrite/dot.html) * [Edge List](readwrite/edgelist.html) * [GEXF](readwrite/gexf.html) * [GML](readwrite/gml.html) * [GraphML](readwrite/graphml.html) * [JSON](readwrite/json_graph.html) * [LEDA](readwrite/leda.html) * [SparseGraph6](readwrite/sparsegraph6.html) * [Pajek](readwrite/pajek.html) * [Matrix Market](readwrite/matrix_market.html) * [Network Text](readwrite/text.html) * [Drawing](drawing.html) * [Matplotlib](drawing.html#module-networkx.drawing.nx_pylab) * [Graphviz AGraph (dot)](drawing.html#module-networkx.drawing.nx_agraph) * [Graphviz with pydot](drawing.html#module-networkx.drawing.nx_pydot) * [Graph Layout](drawing.html#module-networkx.drawing.layout) * [LaTeX Code](drawing.html#module-networkx.drawing.nx_latex) * [Randomness](randomness.html) * [Exceptions](exceptions.html) * [`NetworkXException`](exceptions.html#networkx.NetworkXException) * [`NetworkXError`](exceptions.html#networkx.NetworkXError) * [`NetworkXPointlessConcept`](exceptions.html#networkx.NetworkXPointlessConcept) * [`NetworkXAlgorithmError`](exceptions.html#networkx.NetworkXAlgorithmError) * [`NetworkXUnfeasible`](exceptions.html#networkx.NetworkXUnfeasible) * [`NetworkXNoPath`](exceptions.html#networkx.NetworkXNoPath) * [`NetworkXNoCycle`](exceptions.html#networkx.NetworkXNoCycle) * [`NodeNotFound`](exceptions.html#networkx.NodeNotFound) * [`HasACycle`](exceptions.html#networkx.HasACycle) * [`NetworkXUnbounded`](exceptions.html#networkx.NetworkXUnbounded) * [`NetworkXNotImplemented`](exceptions.html#networkx.NetworkXNotImplemented) * [`AmbiguousSolution`](exceptions.html#networkx.AmbiguousSolution) * [`ExceededMaxIterations`](exceptions.html#networkx.ExceededMaxIterations) * [`PowerIterationFailedConvergence`](exceptions.html#networkx.PowerIterationFailedConvergence) * [Utilities](utils.html) * [Helper Functions](utils.html#module-networkx.utils.misc) * [Data Structures and Algorithms](utils.html#module-networkx.utils.union_find) * [Random Sequence Generators](utils.html#module-networkx.utils.random_sequence) * [Decorators](utils.html#module-networkx.utils.decorators) * [Cuthill-Mckee Ordering](utils.html#module-networkx.utils.rcm) * [Mapped Queue](utils.html#module-networkx.utils.mapped_queue) * [Backends](backends.html) * [Docs for backend users](backends.html#docs-for-backend-users) * [Docs for backend developers](backends.html#docs-for-backend-developers) * [\_dispatchable](generated/networkx.utils.backends._dispatchable.html) * [Configs](configs.html) * [`config`](configs.html#networkx.utils.configs.config) * [`NetworkXConfig`](configs.html#networkx.utils.configs.NetworkXConfig) * [`Config`](configs.html#networkx.utils.configs.Config) * [Glossary](glossary.html) --- # Install — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Install[#](#install "Link to this heading") ============================================ NetworkX requires Python 3.10, 3.11, or 3.12. If you do not already have a Python environment configured on your computer, please see the instructions for installing the full [scientific Python stack](https://scipy.org/install.html) . Below we assume you have the default Python environment already configured on your computer and you intend to install `networkx` inside of it. If you want to create and work with Python virtual environments, please follow instructions on [venv](https://docs.python.org/3/library/venv.html) and [virtual environments](http://docs.python-guide.org/en/latest/dev/virtualenvs/) . First, make sure you have the latest version of `pip` (the Python package manager) installed. If you do not, refer to the [Pip documentation](https://pip.pypa.io/en/stable/installing/) and install `pip` first. Install the released version[#](#install-the-released-version "Link to this heading") -------------------------------------------------------------------------------------- Install the current release of `networkx` with `pip`: $ pip install networkx\[default\] To upgrade to a newer release use the `--upgrade` flag: $ pip install --upgrade networkx\[default\] If you do not have permission to install software systemwide, you can install into your user directory using the `--user` flag: $ pip install --user networkx\[default\] If you do not want to install our dependencies (e.g., `numpy`, `scipy`, etc.), you can use: $ pip install networkx This may be helpful if you are using PyPy or you are working on a project that only needs a limited subset of our functionality and you want to limit the number of dependencies. Alternatively, you can manually download `networkx` from [GitHub](https://github.com/networkx/networkx/releases) or [PyPI](https://pypi.python.org/pypi/networkx) . To install one of these versions, unpack it and run the following from the top-level source directory using the Terminal: $ pip install .\[default\] Install the development version[#](#install-the-development-version "Link to this heading") -------------------------------------------------------------------------------------------- If you have [Git](https://git-scm.com/) installed on your system, it is also possible to install the development version of `networkx`. Before installing the development version, you may need to uninstall the standard version of `networkx` using `pip`: $ pip uninstall networkx Then do: $ git clone https://github.com/networkx/networkx.git $ cd networkx $ pip install -e .\[default\] The `pip install -e .[default]` command allows you to follow the development branch as it changes by creating links in the right places and installing the command line scripts to the appropriate locations. Then, if you want to update `networkx` at any time, in the same directory do: $ git pull Backends[#](#backends "Link to this heading") ---------------------------------------------- NetworkX has the ability to dispatch function calls to optional, separately-installed, third-party backends. NetworkX backends let users experience improved performance and/or additional functionality without changing their NetworkX Python code. While NetworkX is a pure-Python implementation with minimal to no dependencies, backends may be written in other languages and require specialized hardware and/or OS support, additional software dependencies, or even separate services. Installation instructions vary based on the backend, and additional information can be found from the individual backend project pages listed in the [Backends](backends.html) section. Extra packages[#](#extra-packages "Link to this heading") ---------------------------------------------------------- Note Some optional packages may require compiling C or C++ code. If you have difficulty installing these packages with `pip`, please consult the homepages of those packages. The following extra packages provide additional functionality. See the files in the `requirements/` directory for information about specific version requirements. * [PyGraphviz](http://pygraphviz.github.io/) and [pydot](https://github.com/erocarrera/pydot) provide graph drawing and graph layout algorithms via [GraphViz](http://graphviz.org/) . * [lxml](http://lxml.de/) used for GraphML XML format. To install `networkx` and extra packages, do: $ pip install networkx\[default,extra\] To explicitly install all optional packages, do: $ pip install pygraphviz pydot lxml Or, install any optional package (e.g., `pygraphviz`) individually: $ pip install pygraphviz Testing[#](#testing "Link to this heading") -------------------------------------------- NetworkX uses the Python `pytest` testing package. You can learn more about pytest on their [homepage](https://pytest.org) . ### Test a source distribution[#](#test-a-source-distribution "Link to this heading") You can test the complete package from the unpacked source directory with: pytest networkx ### Test an installed package[#](#test-an-installed-package "Link to this heading") From a shell command prompt you can test the installed package with: pytest \--pyargs networkx On this page --- # Software for Complex Networks — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Software for Complex Networks[#](#software-for-complex-networks "Link to this heading") ======================================================================================== Release: 3.4.2 Date: Oct 21, 2024 NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. It provides: * tools for the study of the structure and dynamics of social, biological, and infrastructure networks; * a standard programming interface and graph implementation that is suitable for many applications; * a rapid development environment for collaborative, multidisciplinary projects; * support for algorithm acceleration and additional features through third-party backends; * an interface to existing numerical algorithms and code written in C, C++, and FORTRAN; and * the ability to painlessly work with large nonstandard data sets. With NetworkX you can load and store networks in standard and nonstandard data formats, generate many types of random and classic networks, analyze network structure, build network models, design new network algorithms, draw networks, and much more. Citing[#](#citing "Link to this heading") ------------------------------------------ To cite NetworkX please use the following publication: Aric A. Hagberg, Daniel A. Schult and Pieter J. Swart, [“Exploring network structure, dynamics, and function using NetworkX”](http://conference.scipy.org.s3-website-us-east-1.amazonaws.com/proceedings/scipy2008/paper_2/) , in [Proceedings of the 7th Python in Science Conference (SciPy2008)](http://conference.scipy.org.s3-website-us-east-1.amazonaws.com/proceedings/scipy2008/index.html) , Gäel Varoquaux, Travis Vaught, and Jarrod Millman (Eds), (Pasadena, CA USA), pp. 11–15, Aug 2008 [PDF](http://conference.scipy.org.s3-website-us-east-1.amazonaws.com/proceedings/scipy2008/paper_2/full_text.pdf) [BibTeX](http://conference.scipy.org.s3-website-us-east-1.amazonaws.com/proceedings/scipy2008/paper_2/reference.bib) Audience[#](#audience "Link to this heading") ---------------------------------------------- The audience for NetworkX includes mathematicians, physicists, biologists, computer scientists, and social scientists. Good reviews of the science of complex networks are presented in Albert and Barabási [\[BA02\]](#ba02) , Newman [\[Newman03\]](#newman03) , and Dorogovtsev and Mendes [\[DM03\]](#dm03) . See also the classic texts [\[Bollobas01\]](#bollobas01) , [\[Diestel97\]](#diestel97) and [\[West01\]](#west01) for graph theoretic results and terminology. For basic graph algorithms, we recommend the texts of Sedgewick (e.g., [\[Sedgewick01\]](#sedgewick01) and [\[Sedgewick02\]](#sedgewick02) ) and the survey of Brandes and Erlebach [\[BE05\]](#be05) . Python[#](#python "Link to this heading") ------------------------------------------ Python is a powerful programming language that allows simple and flexible representations of networks as well as clear and concise expressions of network algorithms. Python has a vibrant and growing ecosystem of packages that NetworkX uses to provide more features such as numerical linear algebra and drawing. In order to make the most out of NetworkX you will want to know how to write basic programs in Python. Among the many guides to Python, we recommend the [Python documentation](https://docs.python.org/3/) and the text by Alex Martelli [\[Martelli03\]](#martelli03) . License[#](#license "Link to this heading") -------------------------------------------- NetworkX is distributed with the 3-clause BSD license. Copyright (C) 2004\-2024, NetworkX Developers Aric Hagberg Dan Schult Pieter Swart All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: \* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. \* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. \* Neither the name of the NetworkX Developers nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Bibliography[#](#bibliography "Link to this heading") ------------------------------------------------------ \[[BA02](#id1)\ \] R. Albert and A.-L. Barabási, “Statistical mechanics of complex networks”, Reviews of Modern Physics, 74, pp. 47-97, 2002. [https://arxiv.org/abs/cond-mat/0106096](https://arxiv.org/abs/cond-mat/0106096) \[[Bollobas01](#id4)\ \] B. Bollobás, “Random Graphs”, Second Edition, Cambridge University Press, 2001. \[[BE05](#id9)\ \] U. Brandes and T. Erlebach, “Network Analysis: Methodological Foundations”, Lecture Notes in Computer Science, Volume 3418, Springer-Verlag, 2005. \[[Diestel97](#id5)\ \] R. Diestel, “Graph Theory”, Springer-Verlag, 1997. [http://diestel-graph-theory.com/index.html](http://diestel-graph-theory.com/index.html) \[[DM03](#id3)\ \] S.N. Dorogovtsev and J.F.F. Mendes, “Evolution of Networks”, Oxford University Press, 2003. \[[Martelli03](#id10)\ \] A. Martelli, “Python in a Nutshell”, O’Reilly Media Inc, 2003. \[[Newman03](#id2)\ \] M.E.J. Newman, “The Structure and Function of Complex Networks”, SIAM Review, 45, pp. 167-256, 2003. [http://epubs.siam.org/doi/abs/10.1137/S003614450342480](http://epubs.siam.org/doi/abs/10.1137/S003614450342480) \[[Sedgewick02](#id8)\ \] R. Sedgewick, “Algorithms in C: Parts 1-4: Fundamentals, Data Structure, Sorting, Searching”, Addison Wesley Professional, 3rd ed., 2002. \[[Sedgewick01](#id7)\ \] R. Sedgewick, “Algorithms in C, Part 5: Graph Algorithms”, Addison Wesley Professional, 3rd ed., 2001. \[[West01](#id6)\ \] D. B. West, “Introduction to Graph Theory”, Prentice Hall, 2nd ed., 2001. On this page --- # Backends — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Backends[#](#backends "Link to this heading") ============================================== The following backends are known to work with the current stable release of NetworkX. Backends need not be listed here in order to work, and there may be many backends that NetworkX developers don’t know about. You should be able to install the backend, enable the backend using the `backend=...` keyword arg, the `NETWORKX_BACKEND_PRIORITY` environment variable, or the config setting `nx.config.backend_priority="..."` as described in the [Tutorial](tutorial.html#using-networkx-backends) . See the documentation for a particular backend for a description of the NetworkX functions it provides, how to install it, and any special backend-specific configurations it supports. | Name | Description | | --- | --- | | [nx-parallel](https://github.com/networkx/nx-parallel) | Parallelized implementations of various NetworkX functions using joblib | | [nx-cugraph](https://rapids.ai/nx-cugraph) | GPU acceleration using RAPIDS cuGraph and NVIDIA GPUs | | [nx-arangodb](https://nx-arangodb.readthedocs.io/en/latest/) | Seamlessly adds ArangoDB as a persistence layer to NetworkX graphs | --- # Tutorial — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Tutorial[#](#tutorial "Link to this heading") ============================================== This guide can help you start working with NetworkX. Creating a graph[#](#creating-a-graph "Link to this heading") -------------------------------------------------------------- Create an empty graph with no nodes and no edges. import networkx as nx G \= nx.Graph() By definition, a [`Graph`](reference/classes/graph.html#networkx.Graph "networkx.Graph") is a collection of nodes (vertices) along with identified pairs of nodes (called edges, links, etc). In NetworkX, nodes can be any [hashable](https://docs.python.org/3/glossary.html#term-hashable "(in Python v3.13)") object e.g., a text string, an image, an XML object, another Graph, a customized node object, etc. Note Python’s `None` object is not allowed to be used as a node. It determines whether optional function arguments have been assigned in many functions. Nodes[#](#nodes "Link to this heading") ---------------------------------------- The graph `G` can be grown in several ways. NetworkX includes many [graph generator functions](reference/generators.html) and [facilities to read and write graphs in many formats](reference/readwrite/index.html) . To get started though we’ll look at simple manipulations. You can add one node at a time, G.add\_node(1) or add nodes from any [iterable](https://docs.python.org/3/glossary.html#term-iterable "(in Python v3.13)") container, such as a list G.add\_nodes\_from(\[2, 3\]) You can also add nodes along with node attributes if your container yields 2-tuples of the form `(node, node_attribute_dict)`: G.add\_nodes\_from(\[(4, {"color": "red"}), (5, {"color": "green"})\]) Node attributes are discussed further [below](#attributes) . Nodes from one graph can be incorporated into another: H \= nx.path\_graph(10) G.add\_nodes\_from(H) `G` now contains the nodes of `H` as nodes of `G`. In contrast, you could use the graph `H` as a node in `G`. G.add\_node(H) The graph `G` now contains `H` as a node. This flexibility is very powerful as it allows graphs of graphs, graphs of files, graphs of functions and much more. It is worth thinking about how to structure your application so that the nodes are useful entities. Of course you can always use a unique identifier in `G` and have a separate dictionary keyed by identifier to the node information if you prefer. Note You should not change the node object if the hash depends on its contents. Edges[#](#edges "Link to this heading") ---------------------------------------- `G` can also be grown by adding one edge at a time, G.add\_edge(1, 2) e \= (2, 3) G.add\_edge(\*e) \# unpack edge tuple\* by adding a list of edges, G.add\_edges\_from(\[(1, 2), (1, 3)\]) or by adding any [ebunch](reference/glossary.html#term-ebunch) of edges. An _ebunch_ is any iterable container of edge-tuples. An edge-tuple can be a 2-tuple of nodes or a 3-tuple with 2 nodes followed by an edge attribute dictionary, e.g., `(2, 3, {'weight': 3.1415})`. Edge attributes are discussed further [below](#attributes) . G.add\_edges\_from(H.edges) There are no complaints when adding existing nodes or edges. For example, after removing all nodes and edges, G.clear() we add new nodes/edges and NetworkX quietly ignores any that are already present. G.add\_edges\_from(\[(1, 2), (1, 3)\]) G.add\_node(1) G.add\_edge(1, 2) G.add\_node("spam") \# adds node "spam" G.add\_nodes\_from("spam") \# adds 4 nodes: 's', 'p', 'a', 'm' G.add\_edge(3, 'm') At this stage the graph `G` consists of 8 nodes and 3 edges, as can be seen by: G.number\_of\_nodes() 8 G.number\_of\_edges() 3 Note The order of adjacency reporting (e.g., [`G.adj`](reference/classes/generated/networkx.Graph.adj.html#networkx.Graph.adj "networkx.Graph.adj") , [`G.successors`](reference/classes/generated/networkx.DiGraph.successors.html#networkx.DiGraph.successors "networkx.DiGraph.successors") , [`G.predecessors`](reference/classes/generated/networkx.DiGraph.predecessors.html#networkx.DiGraph.predecessors "networkx.DiGraph.predecessors") ) is the order of edge addition. However, the order of G.edges is the order of the adjacencies which includes both the order of the nodes and each node’s adjacencies. See example below: DG \= nx.DiGraph() DG.add\_edge(2, 1) \# adds the nodes in order 2, 1 DG.add\_edge(1, 3) DG.add\_edge(2, 4) DG.add\_edge(1, 2) assert list(DG.successors(2)) \== \[1, 4\] assert list(DG.edges) \== \[(2, 1), (2, 4), (1, 3), (1, 2)\] Examining elements of a graph[#](#examining-elements-of-a-graph "Link to this heading") ---------------------------------------------------------------------------------------- We can examine the nodes and edges. Four basic graph properties facilitate reporting: `G.nodes`, `G.edges`, `G.adj` and `G.degree`. These are set-like views of the nodes, edges, neighbors (adjacencies), and degrees of nodes in a graph. They offer a continually updated read-only view into the graph structure. They are also dict-like in that you can look up node and edge data attributes via the views and iterate with data attributes using methods `.items()`, `.data()`. If you want a specific container type instead of a view, you can specify one. Here we use lists, though sets, dicts, tuples and other containers may be better in other contexts. list(G.nodes) \[1, 2, 3, 'spam', 's', 'p', 'a', 'm'\] list(G.edges) \[(1, 2), (1, 3), (3, 'm')\] list(G.adj\[1\]) \# or list(G.neighbors(1)) \[2, 3\] G.degree\[1\] \# the number of edges incident to 1 2 One can specify to report the edges and degree from a subset of all nodes using an [nbunch](reference/glossary.html#term-nbunch) . An _nbunch_ is any of: `None` (meaning all nodes), a node, or an iterable container of nodes that is not itself a node in the graph. G.edges(\[2, 'm'\]) EdgeDataView(\[(2, 1), ('m', 3)\]) G.degree(\[2, 3\]) DegreeView({2: 1, 3: 2}) Removing elements from a graph[#](#removing-elements-from-a-graph "Link to this heading") ------------------------------------------------------------------------------------------ One can remove nodes and edges from the graph in a similar fashion to adding. Use methods [`Graph.remove_node()`](reference/classes/generated/networkx.Graph.remove_node.html#networkx.Graph.remove_node "networkx.Graph.remove_node") , [`Graph.remove_nodes_from()`](reference/classes/generated/networkx.Graph.remove_nodes_from.html#networkx.Graph.remove_nodes_from "networkx.Graph.remove_nodes_from") , [`Graph.remove_edge()`](reference/classes/generated/networkx.Graph.remove_edge.html#networkx.Graph.remove_edge "networkx.Graph.remove_edge") and [`Graph.remove_edges_from()`](reference/classes/generated/networkx.Graph.remove_edges_from.html#networkx.Graph.remove_edges_from "networkx.Graph.remove_edges_from") , e.g. G.remove\_node(2) G.remove\_nodes\_from("spam") list(G.nodes) \[1, 3, 'spam'\] G.remove\_edge(1, 3) list(G) \[1, 3, 'spam'\] Using the graph constructors[#](#using-the-graph-constructors "Link to this heading") -------------------------------------------------------------------------------------- Graph objects do not have to be built up incrementally - data specifying graph structure can be passed directly to the constructors of the various graph classes. When creating a graph structure by instantiating one of the graph classes you can specify data in several formats. G.add\_edge(1, 2) H \= nx.DiGraph(G) \# create a DiGraph using the connections from G list(H.edges()) \[(1, 2), (2, 1)\] edgelist \= \[(0, 1), (1, 2), (2, 3)\] H \= nx.Graph(edgelist) \# create a graph from an edge list list(H.edges()) \[(0, 1), (1, 2), (2, 3)\] adjacency\_dict \= {0: (1, 2), 1: (0, 2), 2: (0, 1)} H \= nx.Graph(adjacency\_dict) \# create a Graph dict mapping nodes to nbrs list(H.edges()) \[(0, 1), (0, 2), (1, 2)\] What to use as nodes and edges[#](#what-to-use-as-nodes-and-edges "Link to this heading") ------------------------------------------------------------------------------------------ You might notice that nodes and edges are not specified as NetworkX objects. This leaves you free to use meaningful items as nodes and edges. The most common choices are numbers or strings, but a node can be any hashable object (except `None`), and an edge can be associated with any object `x` using `G.add_edge(n1, n2, object=x)`. As an example, `n1` and `n2` could be protein objects from the RCSB Protein Data Bank, and `x` could refer to an XML record of publications detailing experimental observations of their interaction. We have found this power quite useful, but its abuse can lead to surprising behavior unless one is familiar with Python. If in doubt, consider using [`convert_node_labels_to_integers()`](reference/generated/networkx.relabel.convert_node_labels_to_integers.html#networkx.relabel.convert_node_labels_to_integers "networkx.relabel.convert_node_labels_to_integers") to obtain a more traditional graph with integer labels. Accessing edges and neighbors[#](#accessing-edges-and-neighbors "Link to this heading") ---------------------------------------------------------------------------------------- In addition to the views [`Graph.edges`](reference/classes/generated/networkx.Graph.edges.html#networkx.Graph.edges "networkx.Graph.edges") , and [`Graph.adj`](reference/classes/generated/networkx.Graph.adj.html#networkx.Graph.adj "networkx.Graph.adj") , access to edges and neighbors is possible using subscript notation. G \= nx.Graph(\[(1, 2, {"color": "yellow"})\]) G\[1\] \# same as G.adj\[1\] AtlasView({2: {'color': 'yellow'}}) G\[1\]\[2\] {'color': 'yellow'} G.edges\[1, 2\] {'color': 'yellow'} You can get/set the attributes of an edge using subscript notation if the edge already exists. G.add\_edge(1, 3) G\[1\]\[3\]\['color'\] \= "blue" G.edges\[1, 2\]\['color'\] \= "red" G.edges\[1, 2\] {'color': 'red'} Fast examination of all (node, adjacency) pairs is achieved using `G.adjacency()`, or `G.adj.items()`. Note that for undirected graphs, adjacency iteration sees each edge twice. FG \= nx.Graph() FG.add\_weighted\_edges\_from(\[(1, 2, 0.125), (1, 3, 0.75), (2, 4, 1.2), (3, 4, 0.375)\]) for n, nbrs in FG.adj.items(): for nbr, eattr in nbrs.items(): wt \= eattr\['weight'\] if wt < 0.5: print(f"({n}, {nbr}, {wt:.3})") (1, 2, 0.125) (2, 1, 0.125) (3, 4, 0.375) (4, 3, 0.375) Convenient access to all edges is achieved with the edges property. for (u, v, wt) in FG.edges.data('weight'): if wt < 0.5: print(f"({u}, {v}, {wt:.3})") (1, 2, 0.125) (3, 4, 0.375) Adding attributes to graphs, nodes, and edges[#](#adding-attributes-to-graphs-nodes-and-edges "Link to this heading") ---------------------------------------------------------------------------------------------------------------------- Attributes such as weights, labels, colors, or whatever Python object you like, can be attached to graphs, nodes, or edges. Each graph, node, and edge can hold key/value attribute pairs in an associated attribute dictionary (the keys must be hashable). By default these are empty, but attributes can be added or changed using `add_edge`, `add_node` or direct manipulation of the attribute dictionaries named `G.graph`, `G.nodes`, and `G.edges` for a graph `G`. ### Graph attributes[#](#graph-attributes "Link to this heading") Assign graph attributes when creating a new graph G \= nx.Graph(day\="Friday") G.graph {'day': 'Friday'} Or you can modify attributes later G.graph\['day'\] \= "Monday" G.graph {'day': 'Monday'} ### Node attributes[#](#node-attributes "Link to this heading") Add node attributes using `add_node()`, `add_nodes_from()`, or `G.nodes` G.add\_node(1, time\='5pm') G.add\_nodes\_from(\[3\], time\='2pm') G.nodes\[1\] {'time': '5pm'} G.nodes\[1\]\['room'\] \= 714 G.nodes.data() NodeDataView({1: {'time': '5pm', 'room': 714}, 3: {'time': '2pm'}}) Note that adding a node to `G.nodes` does not add it to the graph, use `G.add_node()` to add new nodes. Similarly for edges. ### Edge Attributes[#](#edge-attributes "Link to this heading") Add/change edge attributes using `add_edge()`, `add_edges_from()`, or subscript notation. G.add\_edge(1, 2, weight\=4.7 ) G.add\_edges\_from(\[(3, 4), (4, 5)\], color\='red') G.add\_edges\_from(\[(1, 2, {'color': 'blue'}), (2, 3, {'weight': 8})\]) G\[1\]\[2\]\['weight'\] \= 4.7 G.edges\[3, 4\]\['weight'\] \= 4.2 The special attribute `weight` should be numeric as it is used by algorithms requiring weighted edges. Directed graphs[#](#directed-graphs "Link to this heading") ------------------------------------------------------------ The [`DiGraph`](reference/classes/digraph.html#networkx.DiGraph "networkx.DiGraph") class provides additional methods and properties specific to directed edges, e.g., [`DiGraph.out_edges`](reference/classes/generated/networkx.DiGraph.out_edges.html#networkx.DiGraph.out_edges "networkx.DiGraph.out_edges") , [`DiGraph.in_degree`](reference/classes/generated/networkx.DiGraph.in_degree.html#networkx.DiGraph.in_degree "networkx.DiGraph.in_degree") , [`DiGraph.predecessors()`](reference/classes/generated/networkx.DiGraph.predecessors.html#networkx.DiGraph.predecessors "networkx.DiGraph.predecessors") , [`DiGraph.successors()`](reference/classes/generated/networkx.DiGraph.successors.html#networkx.DiGraph.successors "networkx.DiGraph.successors") etc. To allow algorithms to work with both classes easily, the directed versions of [`neighbors`](reference/classes/generated/networkx.DiGraph.neighbors.html#networkx.DiGraph.neighbors "networkx.DiGraph.neighbors") is equivalent to [`successors`](reference/classes/generated/networkx.DiGraph.successors.html#networkx.DiGraph.successors "networkx.DiGraph.successors") while [`DiGraph.degree`](reference/classes/generated/networkx.DiGraph.degree.html#networkx.DiGraph.degree "networkx.DiGraph.degree") reports the sum of [`DiGraph.in_degree`](reference/classes/generated/networkx.DiGraph.in_degree.html#networkx.DiGraph.in_degree "networkx.DiGraph.in_degree") and [`DiGraph.out_degree`](reference/classes/generated/networkx.DiGraph.out_degree.html#networkx.DiGraph.out_degree "networkx.DiGraph.out_degree") even though that may feel inconsistent at times. DG \= nx.DiGraph() DG.add\_weighted\_edges\_from(\[(1, 2, 0.5), (3, 1, 0.75)\]) DG.out\_degree(1, weight\='weight') 0.5 DG.degree(1, weight\='weight') 1.25 list(DG.successors(1)) \[2\] list(DG.neighbors(1)) \[2\] Some algorithms work only for directed graphs and others are not well defined for directed graphs. Indeed the tendency to lump directed and undirected graphs together is dangerous. If you want to treat a directed graph as undirected for some measurement you should probably convert it using [`Graph.to_undirected()`](reference/classes/generated/networkx.Graph.to_undirected.html#networkx.Graph.to_undirected "networkx.Graph.to_undirected") or with H \= nx.Graph(G) \# create an undirected graph H from a directed graph G Multigraphs[#](#multigraphs "Link to this heading") ---------------------------------------------------- NetworkX provides classes for graphs which allow multiple edges between any pair of nodes. The [`MultiGraph`](reference/classes/multigraph.html#networkx.MultiGraph "networkx.MultiGraph") and [`MultiDiGraph`](reference/classes/multidigraph.html#networkx.MultiDiGraph "networkx.MultiDiGraph") classes allow you to add the same edge twice, possibly with different edge data. This can be powerful for some applications, but many algorithms are not well defined on such graphs. Where results are well defined, e.g., [`MultiGraph.degree()`](reference/classes/generated/networkx.MultiGraph.degree.html#networkx.MultiGraph.degree "networkx.MultiGraph.degree") we provide the function. Otherwise you should convert to a standard graph in a way that makes the measurement well defined. MG \= nx.MultiGraph() MG.add\_weighted\_edges\_from(\[(1, 2, 0.5), (1, 2, 0.75), (2, 3, 0.5)\]) dict(MG.degree(weight\='weight')) {1: 1.25, 2: 1.75, 3: 0.5} GG \= nx.Graph() for n, nbrs in MG.adjacency(): for nbr, edict in nbrs.items(): minvalue \= min(\[d\['weight'\] for d in edict.values()\]) GG.add\_edge(n, nbr, weight \= minvalue) nx.shortest\_path(GG, 1, 3) \[1, 2, 3\] Graph generators and graph operations[#](#graph-generators-and-graph-operations "Link to this heading") -------------------------------------------------------------------------------------------------------- In addition to constructing graphs node-by-node or edge-by-edge, they can also be generated by ### 1\. Applying classic graph operations, such as:[#](#applying-classic-graph-operations-such-as "Link to this heading") | | | | --- | --- | | [`subgraph`](reference/generated/networkx.classes.function.subgraph.html#networkx.classes.function.subgraph "networkx.classes.function.subgraph")
(G, nbunch) | Returns the subgraph induced on nodes in nbunch. | | [`union`](reference/algorithms/generated/networkx.algorithms.operators.binary.union.html#networkx.algorithms.operators.binary.union "networkx.algorithms.operators.binary.union")
(G, H\[, rename\]) | Combine graphs G and H. | | [`disjoint_union`](reference/algorithms/generated/networkx.algorithms.operators.binary.disjoint_union.html#networkx.algorithms.operators.binary.disjoint_union "networkx.algorithms.operators.binary.disjoint_union")
(G, H) | Combine graphs G and H. | | [`cartesian_product`](reference/algorithms/generated/networkx.algorithms.operators.product.cartesian_product.html#networkx.algorithms.operators.product.cartesian_product "networkx.algorithms.operators.product.cartesian_product")
(G, H) | Returns the Cartesian product of G and H. | | [`compose`](reference/algorithms/generated/networkx.algorithms.operators.binary.compose.html#networkx.algorithms.operators.binary.compose "networkx.algorithms.operators.binary.compose")
(G, H) | Compose graph G with H by combining nodes and edges into a single graph. | | [`complement`](reference/algorithms/generated/networkx.algorithms.operators.unary.complement.html#networkx.algorithms.operators.unary.complement "networkx.algorithms.operators.unary.complement")
(G) | Returns the graph complement of G. | | [`create_empty_copy`](reference/generated/networkx.classes.function.create_empty_copy.html#networkx.classes.function.create_empty_copy "networkx.classes.function.create_empty_copy")
(G\[, with\_data\]) | Returns a copy of the graph G with all of the edges removed. | | [`to_undirected`](reference/generated/networkx.classes.function.to_undirected.html#networkx.classes.function.to_undirected "networkx.classes.function.to_undirected")
(graph) | Returns an undirected view of the graph `graph`. | | [`to_directed`](reference/generated/networkx.classes.function.to_directed.html#networkx.classes.function.to_directed "networkx.classes.function.to_directed")
(graph) | Returns a directed view of the graph `graph`. | ### 2\. Using a call to one of the classic small graphs, e.g.,[#](#using-a-call-to-one-of-the-classic-small-graphs-e-g "Link to this heading") | | | | --- | --- | | [`petersen_graph`](reference/generated/networkx.generators.small.petersen_graph.html#networkx.generators.small.petersen_graph "networkx.generators.small.petersen_graph")
(\[create\_using\]) | Returns the Petersen graph. | | [`tutte_graph`](reference/generated/networkx.generators.small.tutte_graph.html#networkx.generators.small.tutte_graph "networkx.generators.small.tutte_graph")
(\[create\_using\]) | Returns the Tutte graph. | | [`sedgewick_maze_graph`](reference/generated/networkx.generators.small.sedgewick_maze_graph.html#networkx.generators.small.sedgewick_maze_graph "networkx.generators.small.sedgewick_maze_graph")
(\[create\_using\]) | Return a small maze with a cycle. | | [`tetrahedral_graph`](reference/generated/networkx.generators.small.tetrahedral_graph.html#networkx.generators.small.tetrahedral_graph "networkx.generators.small.tetrahedral_graph")
(\[create\_using\]) | Returns the 3-regular Platonic Tetrahedral graph. | ### 3\. Using a (constructive) generator for a classic graph, e.g.,[#](#using-a-constructive-generator-for-a-classic-graph-e-g "Link to this heading") | | | | --- | --- | | [`complete_graph`](reference/generated/networkx.generators.classic.complete_graph.html#networkx.generators.classic.complete_graph "networkx.generators.classic.complete_graph")
(n\[, create\_using\]) | Return the complete graph `K_n` with n nodes. | | [`complete_bipartite_graph`](reference/algorithms/generated/networkx.algorithms.bipartite.generators.complete_bipartite_graph.html#networkx.algorithms.bipartite.generators.complete_bipartite_graph "networkx.algorithms.bipartite.generators.complete_bipartite_graph")
(n1, n2\[, create\_using\]) | Returns the complete bipartite graph `K_{n_1,n_2}`. | | [`barbell_graph`](reference/generated/networkx.generators.classic.barbell_graph.html#networkx.generators.classic.barbell_graph "networkx.generators.classic.barbell_graph")
(m1, m2\[, create\_using\]) | Returns the Barbell Graph: two complete graphs connected by a path. | | [`lollipop_graph`](reference/generated/networkx.generators.classic.lollipop_graph.html#networkx.generators.classic.lollipop_graph "networkx.generators.classic.lollipop_graph")
(m, n\[, create\_using\]) | Returns the Lollipop Graph; `K_m` connected to `P_n`. | like so: K\_5 \= nx.complete\_graph(5) K\_3\_5 \= nx.complete\_bipartite\_graph(3, 5) barbell \= nx.barbell\_graph(10, 10) lollipop \= nx.lollipop\_graph(10, 20) ### 4\. Using a stochastic graph generator, e.g,[#](#using-a-stochastic-graph-generator-e-g "Link to this heading") | | | | --- | --- | | [`erdos_renyi_graph`](reference/generated/networkx.generators.random_graphs.erdos_renyi_graph.html#networkx.generators.random_graphs.erdos_renyi_graph "networkx.generators.random_graphs.erdos_renyi_graph")
(n, p\[, seed, directed, ...\]) | Returns a \\(G\_{n,p}\\) random graph, also known as an Erdős-Rényi graph or a binomial graph. | | [`watts_strogatz_graph`](reference/generated/networkx.generators.random_graphs.watts_strogatz_graph.html#networkx.generators.random_graphs.watts_strogatz_graph "networkx.generators.random_graphs.watts_strogatz_graph")
(n, k, p\[, seed, ...\]) | Returns a Watts–Strogatz small-world graph. | | [`barabasi_albert_graph`](reference/generated/networkx.generators.random_graphs.barabasi_albert_graph.html#networkx.generators.random_graphs.barabasi_albert_graph "networkx.generators.random_graphs.barabasi_albert_graph")
(n, m\[, seed, ...\]) | Returns a random graph using Barabási–Albert preferential attachment | | [`random_lobster`](reference/generated/networkx.generators.random_graphs.random_lobster.html#networkx.generators.random_graphs.random_lobster "networkx.generators.random_graphs.random_lobster")
(n, p1, p2\[, seed, create\_using\]) | Returns a random lobster graph. | like so: er \= nx.erdos\_renyi\_graph(100, 0.15) ws \= nx.watts\_strogatz\_graph(30, 3, 0.1) ba \= nx.barabasi\_albert\_graph(100, 5) red \= nx.random\_lobster(100, 0.9, 0.9) ### 5\. Reading a graph stored in a file using common graph formats[#](#reading-a-graph-stored-in-a-file-using-common-graph-formats "Link to this heading") NetworkX supports many popular formats, such as edge lists, adjacency lists, GML, GraphML, LEDA and others. nx.write\_gml(red, "path.to.file") mygraph \= nx.read\_gml("path.to.file") For details on graph formats see [Reading and writing graphs](reference/readwrite/index.html) and for graph generator functions see [Graph generators](reference/generators.html) Analyzing graphs[#](#analyzing-graphs "Link to this heading") -------------------------------------------------------------- The structure of `G` can be analyzed using various graph-theoretic functions such as: G \= nx.Graph() G.add\_edges\_from(\[(1, 2), (1, 3)\]) G.add\_node("spam") \# adds node "spam" list(nx.connected\_components(G)) \[{1, 2, 3}, {'spam'}\] sorted(d for n, d in G.degree()) \[0, 1, 1, 2\] nx.clustering(G) {1: 0, 2: 0, 3: 0, 'spam': 0} Some functions with large output iterate over (node, value) 2-tuples. These are easily stored in a `dict` structure if you desire. sp \= dict(nx.all\_pairs\_shortest\_path(G)) sp\[3\] {3: \[3\], 1: \[3, 1\], 2: \[3, 1, 2\]} See [Algorithms](reference/algorithms/index.html) for details on graph algorithms supported. Using NetworkX backends[#](#using-networkx-backends "Link to this heading") ---------------------------------------------------------------------------- NetworkX can be configured to use separate thrid-party backends to improve performance and add functionality. Backends are optional, installed separately, and can be enabled either directly in the user’s code or through environment variables. Several backends are available to accelerate NetworkX–often significantly–using GPUs, parallel processing, and other optimizations, while other backends add additional features such as graph database integration. Multiple backends can be used together to compose a NetworkX runtime environment optimized for a particular system or use case. Note Refer to the [Backends](backends.html) section to see a list of available backends known to work with the current stable release of NetworkX. NetworkX uses backends by **_dispatching_** function calls at runtime to corresponding functions provided by backends, either **automatically** via configuration variables, or **explicitly** by hard-coded arguments to functions. ### Automatic dispatch[#](#automatic-dispatch "Link to this heading") Automatic dispatch is possibly the easiest and least intrusive means by which a user can use backends with NetworkX code. This technique is useful for users that want to write portable code that runs on systems without specific backends, or simply want to use backends for existing code without modifications. The example below configures NetworkX to automatically dispatch to a backend named `fast_backend` for all NetworkX functions that `fast_backend` supports. * If `fast_backend` does not support a NetworkX function used by the application, the default NetworkX implementation for that function will be used. * If `fast_backend` is not installed on the system running this code, an exception will be raised. bash$> NETWORKX\_BACKEND\_PRIORITY=fast\_backend python my\_script.py my\_script.py[#](#id2 "Link to this code") import networkx as nx G \= nx.karate\_club\_graph() pr \= nx.pagerank(G) \# runs using backend from NETWORKX\_BACKEND\_PRIORITY, if set The equivalent configuration can be applied to NetworkX directly to the code through the NetworkX `config` global parameters, which may be useful if environment variables are not suitable. This will override the corresponding environment variable allowing backends to be enabled programatically in Python code. However, the tradeoff is slightly less portability as updating the backend specification may require a small code change instead of simply updating an environment variable. nx.config.backend\_priority \= \["fast\_backend"\] pr \= nx.pagerank(G) Automatic dispatch using the `NETWORKX_BACKEND_PRIORITY` environment variable or the `nx.config.backend_priority` global config also allows for the specification of multiple backends, ordered based on the priority which NetworkX should attempt to dispatch to. The following examples both configure NetworkX to dispatch functions first to `fast_backend` if it supports the function, then `other_backend` if `fast_backend` does not, then finally the default NetworkX implementation if no backend specified can handle the call. bash$> NETWORKX\_BACKEND\_PRIORITY="fast\_backend,other\_backend" python my\_script.py nx.config.backend\_priority \= \["fast\_backend", "other\_backend"\] Tip NetworkX includes debug logging calls using Python’s standard logging mechanism. These can be enabled to help users understand when and how backends are being used. To enable debug logging only in NetworkX modules: import logging \_l \= logging.getLogger("networkx") \_l.addHandler(\_h:=logging.StreamHandler()) \_h.setFormatter(logging.Formatter("%(levelname)s:NetworkX:%(message)s")) \_l.setLevel(logging.DEBUG) or to enable it globally: logging.basicConfig(level\=logging.DEBUG) ### Explicit dispatch[#](#explicit-dispatch "Link to this heading") Backends can also be used explicitly on a per-function call basis by specifying a backend using the `backend=` keyword argument. This technique not only requires that the backend is installed, but _also_ requires that the backend implement the function, since NetworkX will not fall back to the default NetworkX implementation if a backend is specified with `backend=`. This is possibly the least portable option, but has the advantage that NetworkX will raise an exception if `fast_backend` cannot be used, which is useful for users that require a specific implementation. Explicit dispatch can also provide a more interactive experience and is especially useful for demonstrations, experimentation, and debugging. pr \= nx.pagerank(G, backend\="fast\_backend") ### Advanced dispatching options[#](#advanced-dispatching-options "Link to this heading") The NetworkX dispatcher allows users to use backends for NetworkX code in very specific ways not covered in this tutorial. Refer to the [Backends](reference/backends.html) reference section for details on topics such as: * Control of how specific function types (algorithms vs. generators) are dispatched to specific backends * Details on automatic conversions to/from backend and NetworkX graphs for dispatch and fallback * Caching graph conversions * Explicit backend graph instantiation and dispatching based on backend graph types * and more… Drawing graphs[#](#drawing-graphs "Link to this heading") ---------------------------------------------------------- NetworkX is not primarily a graph drawing package but basic drawing with Matplotlib as well as an interface to use the open source Graphviz software package are included. These are part of the [networkx.drawing](reference/drawing.html) module and will be imported if possible. First import Matplotlib’s plot interface (pylab works too) import matplotlib.pyplot as plt To test if the import of `~networkx.drawing.nx_pylab` was successful draw `G` using one of G \= nx.petersen\_graph() subax1 \= plt.subplot(121) nx.draw(G, with\_labels\=True, font\_weight\='bold') subax2 \= plt.subplot(122) nx.draw\_shell(G, nlist\=\[range(5, 10), range(5)\], with\_labels\=True, font\_weight\='bold') ![_images/b91042efb2e607c59c4207e1d1118cad7fc78e2b5dd01ae957bb1067cbf8edcd.png](_images/b91042efb2e607c59c4207e1d1118cad7fc78e2b5dd01ae957bb1067cbf8edcd.png) when drawing to an interactive display. Note that you may need to issue a Matplotlib plt.show() command if you are not using matplotlib in interactive mode. options \= { 'node\_color': 'black', 'node\_size': 100, 'width': 3, } subax1 \= plt.subplot(221) nx.draw\_random(G, \*\*options) subax2 \= plt.subplot(222) nx.draw\_circular(G, \*\*options) subax3 \= plt.subplot(223) nx.draw\_spectral(G, \*\*options) subax4 \= plt.subplot(224) nx.draw\_shell(G, nlist\=\[range(5,10), range(5)\], \*\*options) ![_images/33974b662ab27058ce0a6a9175e7474821b7f7aaa40bea306cac11362889d775.png](_images/33974b662ab27058ce0a6a9175e7474821b7f7aaa40bea306cac11362889d775.png) You can find additional options via [`draw_networkx()`](reference/generated/networkx.drawing.nx_pylab.draw_networkx.html#networkx.drawing.nx_pylab.draw_networkx "networkx.drawing.nx_pylab.draw_networkx") and layouts via the [`layout module`](reference/drawing.html#module-networkx.drawing.layout "networkx.drawing.layout") . You can use multiple shells with [`draw_shell()`](reference/generated/networkx.drawing.nx_pylab.draw_shell.html#networkx.drawing.nx_pylab.draw_shell "networkx.drawing.nx_pylab.draw_shell") . G \= nx.dodecahedral\_graph() shells \= \[\[2, 3, 4, 5, 6\], \[8, 1, 0, 19, 18, 17, 16, 15, 14, 7\], \[9, 10, 11, 12, 13\]\] nx.draw\_shell(G, nlist\=shells, \*\*options) ![_images/869502982e49e8a4db02c37c3f5d8b5b9d19a340e66423009a619c6523ee3560.png](_images/869502982e49e8a4db02c37c3f5d8b5b9d19a340e66423009a619c6523ee3560.png) To save drawings to a file, use, for example \>>> nx.draw(G) \>>> plt.savefig("path.png") This function writes to the file `path.png` in the local directory. If Graphviz and PyGraphviz or pydot, are available on your system, you can also use `networkx.drawing.nx_agraph.graphviz_layout` or `networkx.drawing.nx_pydot.graphviz_layout` to get the node positions, or write the graph in dot format for further processing. \>>> from networkx.drawing.nx\_pydot import write\_dot \>>> pos \= nx.nx\_agraph.graphviz\_layout(G) \>>> nx.draw(G, pos\=pos) \>>> write\_dot(G, 'file.dot') See [Drawing](reference/drawing.html) for additional details. NX-Guides[#](#nx-guides "Link to this heading") ------------------------------------------------ If you are interested in learning more about NetworkX, graph theory and network analysis then you should check out [nx-guides](https://networkx.org/nx-guides/index.html "(in nx-guides)") . There you can find tutorials, real-world applications and in-depth examinations of graphs and network algorithms. All the material is official and was developed and curated by the NetworkX community. On this page --- # Gallery — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Gallery[#](#gallery "Link to this heading") ============================================ General-purpose and introductory examples for NetworkX. The [tutorial](../tutorial.html) introduces conventions and basic graph manipulations. Basic[#](#basic "Link to this heading") ---------------------------------------- ![](../_images/sphx_glr_plot_properties_thumb.png) [Properties](basic/plot_properties.html#sphx-glr-auto-examples-basic-plot-properties-py) Properties ![](../_images/sphx_glr_plot_read_write_thumb.png) [Read and write graphs.](basic/plot_read_write.html#sphx-glr-auto-examples-basic-plot-read-write-py) Read and write graphs. ![](../_images/sphx_glr_plot_simple_graph_thumb.png) [Simple graph](basic/plot_simple_graph.html#sphx-glr-auto-examples-basic-plot-simple-graph-py) Simple graph Drawing[#](#drawing "Link to this heading") -------------------------------------------- ![](../_images/sphx_glr_plot_center_node_thumb.png) [Custom Node Position](drawing/plot_center_node.html#sphx-glr-auto-examples-drawing-plot-center-node-py) Custom Node Position ![](../_images/sphx_glr_plot_chess_masters_thumb.png) [Chess Masters](drawing/plot_chess_masters.html#sphx-glr-auto-examples-drawing-plot-chess-masters-py) Chess Masters ![](../_images/sphx_glr_plot_clusters_thumb.png) [Cluster Layout](drawing/plot_clusters.html#sphx-glr-auto-examples-drawing-plot-clusters-py) Cluster Layout ![](../_images/sphx_glr_plot_custom_node_icons_thumb.png) [Custom node icons](drawing/plot_custom_node_icons.html#sphx-glr-auto-examples-drawing-plot-custom-node-icons-py) Custom node icons ![](../_images/sphx_glr_plot_degree_thumb.png) [Degree Analysis](drawing/plot_degree.html#sphx-glr-auto-examples-drawing-plot-degree-py) Degree Analysis ![](../_images/sphx_glr_plot_directed_thumb.png) [Directed Graph](drawing/plot_directed.html#sphx-glr-auto-examples-drawing-plot-directed-py) Directed Graph ![](../_images/sphx_glr_plot_edge_colormap_thumb.png) [Edge Colormap](drawing/plot_edge_colormap.html#sphx-glr-auto-examples-drawing-plot-edge-colormap-py) Edge Colormap ![](../_images/sphx_glr_plot_ego_graph_thumb.png) [Ego Graph](drawing/plot_ego_graph.html#sphx-glr-auto-examples-drawing-plot-ego-graph-py) Ego Graph ![](../_images/sphx_glr_plot_eigenvalues_thumb.png) [Eigenvalues](drawing/plot_eigenvalues.html#sphx-glr-auto-examples-drawing-plot-eigenvalues-py) Eigenvalues ![](../_images/sphx_glr_plot_four_grids_thumb.png) [Four Grids](drawing/plot_four_grids.html#sphx-glr-auto-examples-drawing-plot-four-grids-py) Four Grids ![](../_images/sphx_glr_plot_house_with_colors_thumb.png) [House With Colors](drawing/plot_house_with_colors.html#sphx-glr-auto-examples-drawing-plot-house-with-colors-py) House With Colors ![](../_images/sphx_glr_plot_knuth_miles_thumb.png) [Knuth Miles](drawing/plot_knuth_miles.html#sphx-glr-auto-examples-drawing-plot-knuth-miles-py) Knuth Miles ![](../_images/sphx_glr_plot_labels_and_colors_thumb.png) [Labels And Colors](drawing/plot_labels_and_colors.html#sphx-glr-auto-examples-drawing-plot-labels-and-colors-py) Labels And Colors ![](../_images/sphx_glr_plot_multigraphs_thumb.png) [Plotting MultiDiGraph Edges and Labels](drawing/plot_multigraphs.html#sphx-glr-auto-examples-drawing-plot-multigraphs-py) Plotting MultiDiGraph Edges and Labels ![](../_images/sphx_glr_plot_multipartite_graph_thumb.png) [Multipartite Layout](drawing/plot_multipartite_graph.html#sphx-glr-auto-examples-drawing-plot-multipartite-graph-py) Multipartite Layout ![](../_images/sphx_glr_plot_node_colormap_thumb.png) [Node Colormap](drawing/plot_node_colormap.html#sphx-glr-auto-examples-drawing-plot-node-colormap-py) Node Colormap ![](../_images/sphx_glr_plot_rainbow_coloring_thumb.png) [Rainbow Coloring](drawing/plot_rainbow_coloring.html#sphx-glr-auto-examples-drawing-plot-rainbow-coloring-py) Rainbow Coloring ![](../_images/sphx_glr_plot_random_geometric_graph_thumb.png) [Random Geometric Graph](drawing/plot_random_geometric_graph.html#sphx-glr-auto-examples-drawing-plot-random-geometric-graph-py) Random Geometric Graph ![](../_images/sphx_glr_plot_sampson_thumb.png) [Sampson](drawing/plot_sampson.html#sphx-glr-auto-examples-drawing-plot-sampson-py) Sampson ![](../_images/sphx_glr_plot_selfloops_thumb.png) [Self-loops](drawing/plot_selfloops.html#sphx-glr-auto-examples-drawing-plot-selfloops-py) Self-loops ![](../_images/sphx_glr_plot_simple_path_thumb.png) [Simple Path](drawing/plot_simple_path.html#sphx-glr-auto-examples-drawing-plot-simple-path-py) Simple Path ![](../_images/sphx_glr_plot_spectral_grid_thumb.png) [Spectral Embedding](drawing/plot_spectral_grid.html#sphx-glr-auto-examples-drawing-plot-spectral-grid-py) Spectral Embedding ![](../_images/sphx_glr_plot_tsp_thumb.png) [Traveling Salesman Problem](drawing/plot_tsp.html#sphx-glr-auto-examples-drawing-plot-tsp-py) Traveling Salesman Problem ![](../_images/sphx_glr_plot_unix_email_thumb.png) [Unix Email](drawing/plot_unix_email.html#sphx-glr-auto-examples-drawing-plot-unix-email-py) Unix Email ![](../_images/sphx_glr_plot_weighted_graph_thumb.png) [Weighted Graph](drawing/plot_weighted_graph.html#sphx-glr-auto-examples-drawing-plot-weighted-graph-py) Weighted Graph 3D Drawing[#](#d-drawing "Link to this heading") ------------------------------------------------- ![](../_images/sphx_glr_mayavi2_spring_thumb.png) [Mayavi2](3d_drawing/mayavi2_spring.html#sphx-glr-auto-examples-3d-drawing-mayavi2-spring-py) Mayavi2 ![](../_images/sphx_glr_plot_3d_rotation_animation_thumb.gif) [Animations of 3D rotation and random walk](3d_drawing/plot_3d_rotation_animation.html#sphx-glr-auto-examples-3d-drawing-plot-3d-rotation-animation-py) Animations of 3D rotation and random walk ![](../_images/sphx_glr_plot_basic_thumb.png) [Basic matplotlib](3d_drawing/plot_basic.html#sphx-glr-auto-examples-3d-drawing-plot-basic-py) Basic matplotlib Graphviz Layout[#](#graphviz-layout "Link to this heading") ------------------------------------------------------------ Examples using Graphviz layouts with [`nx_pylab`](../reference/drawing.html#module-networkx.drawing.nx_pylab "networkx.drawing.nx_pylab") for drawing. These examples need Graphviz and [PyGraphviz](https://pygraphviz.github.io/documentation/stable/index.html "(in PyGraphviz v1.14)") . ![](../_images/sphx_glr_plot_atlas_thumb.png) [Atlas](graphviz_layout/plot_atlas.html#sphx-glr-auto-examples-graphviz-layout-plot-atlas-py) Atlas ![](../_images/sphx_glr_plot_circular_tree_thumb.png) [Circular Tree](graphviz_layout/plot_circular_tree.html#sphx-glr-auto-examples-graphviz-layout-plot-circular-tree-py) Circular Tree ![](../_images/sphx_glr_plot_decomposition_thumb.png) [Decomposition](graphviz_layout/plot_decomposition.html#sphx-glr-auto-examples-graphviz-layout-plot-decomposition-py) Decomposition ![](../_images/sphx_glr_plot_giant_component_thumb.png) [Giant Component](graphviz_layout/plot_giant_component.html#sphx-glr-auto-examples-graphviz-layout-plot-giant-component-py) Giant Component ![](../_images/sphx_glr_plot_lanl_routes_thumb.png) [Lanl Routes](graphviz_layout/plot_lanl_routes.html#sphx-glr-auto-examples-graphviz-layout-plot-lanl-routes-py) Lanl Routes Graphviz Drawing[#](#graphviz-drawing "Link to this heading") -------------------------------------------------------------- Examples using Graphviz for layout and drawing via [`nx_agraph`](../reference/drawing.html#module-networkx.drawing.nx_agraph "networkx.drawing.nx_agraph") . These examples need Graphviz and [PyGraphviz](https://pygraphviz.github.io/documentation/stable/index.html "(in PyGraphviz v1.14)") . ![](../_images/sphx_glr_plot_attributes_thumb.png) [Attributes](graphviz_drawing/plot_attributes.html#sphx-glr-auto-examples-graphviz-drawing-plot-attributes-py) Attributes ![](../_images/sphx_glr_plot_conversion_thumb.png) [Conversion](graphviz_drawing/plot_conversion.html#sphx-glr-auto-examples-graphviz-drawing-plot-conversion-py) Conversion ![](../_images/sphx_glr_plot_grid_thumb.png) [2D Grid](graphviz_drawing/plot_grid.html#sphx-glr-auto-examples-graphviz-drawing-plot-grid-py) 2D Grid ![](../_images/sphx_glr_plot_mini_atlas_thumb.png) [Atlas](graphviz_drawing/plot_mini_atlas.html#sphx-glr-auto-examples-graphviz-drawing-plot-mini-atlas-py) Atlas Graph[#](#graph "Link to this heading") ---------------------------------------- ![](../_images/sphx_glr_plot_dag_layout_thumb.png) [DAG - Topological Layout](graph/plot_dag_layout.html#sphx-glr-auto-examples-graph-plot-dag-layout-py) DAG - Topological Layout ![](../_images/sphx_glr_plot_degree_sequence_thumb.png) [Degree Sequence](graph/plot_degree_sequence.html#sphx-glr-auto-examples-graph-plot-degree-sequence-py) Degree Sequence ![](../_images/sphx_glr_plot_erdos_renyi_thumb.png) [Erdos Renyi](graph/plot_erdos_renyi.html#sphx-glr-auto-examples-graph-plot-erdos-renyi-py) Erdos Renyi ![](../_images/sphx_glr_plot_expected_degree_sequence_thumb.png) [Expected Degree Sequence](graph/plot_expected_degree_sequence.html#sphx-glr-auto-examples-graph-plot-expected-degree-sequence-py) Expected Degree Sequence ![](../_images/sphx_glr_plot_football_thumb.png) [Football](graph/plot_football.html#sphx-glr-auto-examples-graph-plot-football-py) Football ![](../_images/sphx_glr_plot_karate_club_thumb.png) [Karate Club](graph/plot_karate_club.html#sphx-glr-auto-examples-graph-plot-karate-club-py) Karate Club ![](../_images/sphx_glr_plot_morse_trie_thumb.png) [Morse Trie](graph/plot_morse_trie.html#sphx-glr-auto-examples-graph-plot-morse-trie-py) Morse Trie ![](../_images/sphx_glr_plot_mst_thumb.png) [Minimum Spanning Tree](graph/plot_mst.html#sphx-glr-auto-examples-graph-plot-mst-py) Minimum Spanning Tree ![](../_images/sphx_glr_plot_napoleon_russian_campaign_thumb.png) [Napoleon Russian Campaign](graph/plot_napoleon_russian_campaign.html#sphx-glr-auto-examples-graph-plot-napoleon-russian-campaign-py) Napoleon Russian Campaign ![](../_images/sphx_glr_plot_roget_thumb.png) [Roget](graph/plot_roget.html#sphx-glr-auto-examples-graph-plot-roget-py) Roget ![](../_images/sphx_glr_plot_triad_types_thumb.png) [Triads](graph/plot_triad_types.html#sphx-glr-auto-examples-graph-plot-triad-types-py) Triads ![](../_images/sphx_glr_plot_visibility_graph_thumb.png) [Visibility Graph](graph/plot_visibility_graph.html#sphx-glr-auto-examples-graph-plot-visibility-graph-py) Visibility Graph ![](../_images/sphx_glr_plot_words_thumb.png) [Words/Ladder Graph](graph/plot_words.html#sphx-glr-auto-examples-graph-plot-words-py) Words/Ladder Graph Algorithms[#](#algorithms "Link to this heading") -------------------------------------------------- ![](../_images/sphx_glr_plot_beam_search_thumb.png) [Beam Search](algorithms/plot_beam_search.html#sphx-glr-auto-examples-algorithms-plot-beam-search-py) Beam Search ![](../_images/sphx_glr_plot_betweenness_centrality_thumb.png) [Betweenness Centrality](algorithms/plot_betweenness_centrality.html#sphx-glr-auto-examples-algorithms-plot-betweenness-centrality-py) Betweenness Centrality ![](../_images/sphx_glr_plot_blockmodel_thumb.png) [Blockmodel](algorithms/plot_blockmodel.html#sphx-glr-auto-examples-algorithms-plot-blockmodel-py) Blockmodel ![](../_images/sphx_glr_plot_circuits_thumb.png) [Circuits](algorithms/plot_circuits.html#sphx-glr-auto-examples-algorithms-plot-circuits-py) Circuits ![](../_images/sphx_glr_plot_cycle_detection_thumb.png) [Cycle Detection](algorithms/plot_cycle_detection.html#sphx-glr-auto-examples-algorithms-plot-cycle-detection-py) Cycle Detection ![](../_images/sphx_glr_plot_davis_club_thumb.png) [Davis Club](algorithms/plot_davis_club.html#sphx-glr-auto-examples-algorithms-plot-davis-club-py) Davis Club ![](../_images/sphx_glr_plot_dedensification_thumb.png) [Dedensification](algorithms/plot_dedensification.html#sphx-glr-auto-examples-algorithms-plot-dedensification-py) Dedensification ![](../_images/sphx_glr_plot_girvan_newman_thumb.png) [Community Detection using Girvan-Newman](algorithms/plot_girvan_newman.html#sphx-glr-auto-examples-algorithms-plot-girvan-newman-py) Community Detection using Girvan-Newman ![](../_images/sphx_glr_plot_greedy_coloring_thumb.png) [Greedy Coloring](algorithms/plot_greedy_coloring.html#sphx-glr-auto-examples-algorithms-plot-greedy-coloring-py) Greedy Coloring ![](../_images/sphx_glr_plot_image_segmentation_spectral_graph_partition_thumb.png) [Image Segmentation via Spectral Graph Partitioning](algorithms/plot_image_segmentation_spectral_graph_partition.html#sphx-glr-auto-examples-algorithms-plot-image-segmentation-spectral-graph-partition-py) Image Segmentation via Spectral Graph Partitioning ![](../_images/sphx_glr_plot_iterated_dynamical_systems_thumb.png) [Iterated Dynamical Systems](algorithms/plot_iterated_dynamical_systems.html#sphx-glr-auto-examples-algorithms-plot-iterated-dynamical-systems-py) Iterated Dynamical Systems ![](../_images/sphx_glr_plot_krackhardt_centrality_thumb.png) [Krackhardt Centrality](algorithms/plot_krackhardt_centrality.html#sphx-glr-auto-examples-algorithms-plot-krackhardt-centrality-py) Krackhardt Centrality ![](../_images/sphx_glr_plot_lca_thumb.png) [Lowest Common Ancestors](algorithms/plot_lca.html#sphx-glr-auto-examples-algorithms-plot-lca-py) Lowest Common Ancestors ![](../_images/sphx_glr_plot_maximum_independent_set_thumb.png) [Maximum Independent Set](algorithms/plot_maximum_independent_set.html#sphx-glr-auto-examples-algorithms-plot-maximum-independent-set-py) Maximum Independent Set ![](../_images/sphx_glr_plot_parallel_betweenness_thumb.png) [Parallel Betweenness](algorithms/plot_parallel_betweenness.html#sphx-glr-auto-examples-algorithms-plot-parallel-betweenness-py) Parallel Betweenness ![](../_images/sphx_glr_plot_rcm_thumb.png) [Reverse Cuthill–McKee](algorithms/plot_rcm.html#sphx-glr-auto-examples-algorithms-plot-rcm-py) Reverse Cuthill--McKee ![](../_images/sphx_glr_plot_shortest_path_thumb.png) [Find Shortest Path](algorithms/plot_shortest_path.html#sphx-glr-auto-examples-algorithms-plot-shortest-path-py) Find Shortest Path ![](../_images/sphx_glr_plot_snap_thumb.png) [SNAP Graph Summary](algorithms/plot_snap.html#sphx-glr-auto-examples-algorithms-plot-snap-py) SNAP Graph Summary ![](../_images/sphx_glr_plot_subgraphs_thumb.png) [Subgraphs](algorithms/plot_subgraphs.html#sphx-glr-auto-examples-algorithms-plot-subgraphs-py) Subgraphs External libraries[#](#external-libraries "Link to this heading") ------------------------------------------------------------------ Examples of using NetworkX with external libraries. ![](../_images/sphx_glr_javascript_force_thumb.png) [JavaScript](external/javascript_force.html#sphx-glr-auto-examples-external-javascript-force-py) JavaScript ![](../_images/sphx_glr_plot_igraph_thumb.png) [igraph](external/plot_igraph.html#sphx-glr-auto-examples-external-plot-igraph-py) igraph Geospatial[#](#geospatial "Link to this heading") -------------------------------------------------- The following geospatial examples showcase different ways of performing network analyses using packages within the geospatial Python ecosystem. Example spatial files are stored directly in this directory. See the [extended description](geospatial/extended_description.html) for more details. ![](../_images/sphx_glr_plot_delaunay_thumb.png) [Delaunay graphs from geographic points](geospatial/plot_delaunay.html#sphx-glr-auto-examples-geospatial-plot-delaunay-py) Delaunay graphs from geographic points ![](../_images/sphx_glr_plot_lines_thumb.png) [Graphs from a set of lines](geospatial/plot_lines.html#sphx-glr-auto-examples-geospatial-plot-lines-py) Graphs from a set of lines ![](../_images/sphx_glr_plot_osmnx_thumb.png) [OpenStreetMap with OSMnx](geospatial/plot_osmnx.html#sphx-glr-auto-examples-geospatial-plot-osmnx-py) OpenStreetMap with OSMnx ![](../_images/sphx_glr_plot_points_thumb.png) [Graphs from geographic points](geospatial/plot_points.html#sphx-glr-auto-examples-geospatial-plot-points-py) Graphs from geographic points ![](../_images/sphx_glr_plot_polygons_thumb.png) [Graphs from Polygons](geospatial/plot_polygons.html#sphx-glr-auto-examples-geospatial-plot-polygons-py) Graphs from Polygons Subclass[#](#subclass "Link to this heading") ---------------------------------------------- ![](../_images/sphx_glr_plot_antigraph_thumb.png) [Antigraph](subclass/plot_antigraph.html#sphx-glr-auto-examples-subclass-plot-antigraph-py) Antigraph ![](../_images/sphx_glr_plot_printgraph_thumb.png) [Print Graph](subclass/plot_printgraph.html#sphx-glr-auto-examples-subclass-plot-printgraph-py) Print Graph [`Download all examples in Python source code: auto_examples_python.zip`](../_downloads/07fcc19ba03226cd3d83d4e40ec44385/auto_examples_python.zip) [`Download all examples in Jupyter notebooks: auto_examples_jupyter.zip`](../_downloads/6f1e7a639e0699d6164445b55e6c116d/auto_examples_jupyter.zip) [Gallery generated by Sphinx-Gallery](https://sphinx-gallery.github.io) On this page --- # Developer — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Developer[#](#developer "Link to this heading") ================================================ Release: 3.4.2 Date: Oct 21, 2024 * [About Us](about_us.html) * [Core Developers](about_us.html#core-developers) * [Emeritus Developers](about_us.html#emeritus-developers) * [Steering Council](about_us.html#steering-council) * [Contributors](about_us.html#contributors) * [Support](about_us.html#support) * [Code of Conduct](code_of_conduct.html) * [Introduction](code_of_conduct.html#introduction) * [Specific Guidelines](code_of_conduct.html#specific-guidelines) * [Diversity Statement](code_of_conduct.html#diversity-statement) * [Reporting Guidelines](code_of_conduct.html#reporting-guidelines) * [Incident reporting resolution & Code of Conduct enforcement](code_of_conduct.html#incident-reporting-resolution-code-of-conduct-enforcement) * [Endnotes](code_of_conduct.html#endnotes) * [Mission and Values](values.html) * [Our mission](values.html#our-mission) * [Our values](values.html#our-values) * [Acknowledgments](values.html#acknowledgments) * [Contributor Guide](contribute.html) * [Development Workflow](contribute.html#development-workflow) * [Divergence from `upstream main`](contribute.html#divergence-from-upstream-main) * [Guidelines](contribute.html#guidelines) * [Testing](contribute.html#testing) * [Documentation](contribute.html#documentation) * [Bugs](contribute.html#bugs) * [Policies](contribute.html#policies) * [Mentored Projects](projects.html) * [Pedagogical Interactive Notebooks for Algorithms Implemented in NetworkX](projects.html#pedagogical-interactive-notebooks-for-algorithms-implemented-in-networkx) * [Visualization API with Matplotlib](projects.html#visualization-api-with-matplotlib) * [Incorporate a Python library for ISMAGs isomorphism calculations](projects.html#incorporate-a-python-library-for-ismags-isomorphism-calculations) * [Centrality Atlas](projects.html#centrality-atlas) * [Completed Projects](projects.html#completed-projects) * [New Contributor FAQ](new_contributor_faq.html) * [Q: I’m new to open source and would like to contribute to NetworkX. How do I get started?](new_contributor_faq.html#q-i-m-new-to-open-source-and-would-like-to-contribute-to-networkx-how-do-i-get-started) * [Q: I’ve found an issue I’m interested in, can I have it assigned to me?](new_contributor_faq.html#q-i-ve-found-an-issue-i-m-interested-in-can-i-have-it-assigned-to-me) * [Q: How do I contribute an example to the Gallery?](new_contributor_faq.html#q-how-do-i-contribute-an-example-to-the-gallery) * [Q: I want to work on a specific function. How do I find it in the source code?](new_contributor_faq.html#q-i-want-to-work-on-a-specific-function-how-do-i-find-it-in-the-source-code) * [Q: What is the policy for deciding whether to include a new algorithm?](new_contributor_faq.html#q-what-is-the-policy-for-deciding-whether-to-include-a-new-algorithm) * [Core Developer Guide](core_developer.html) * [Reviewing](core_developer.html#reviewing) * [Closing issues and pull requests](core_developer.html#closing-issues-and-pull-requests) * [Further resources](core_developer.html#further-resources) * [Release Process](release.html) * [Deprecations](deprecations.html) * [Policy](deprecations.html#policy) * [Todo](deprecations.html#todo) * [Roadmap](roadmap.html) * [Installation](roadmap.html#installation) * [Sustainability](roadmap.html#sustainability) * [Performance](roadmap.html#performance) * [Documentation](roadmap.html#documentation) * [Linear Algebra](roadmap.html#linear-algebra) * [Interoperability](roadmap.html#interoperability) * [Visualization](roadmap.html#visualization) * [NXEPs](nxeps/index.html) * [NXEP 0 — Purpose and Process](nxeps/nxep-0000.html) * [NXEP 1 — Governance and Decision Making](nxeps/nxep-0001.html) * [NXEP 2 — API design of view slices](nxeps/nxep-0002.html) * [NXEP 3 — Graph Builders](nxeps/nxep-0003.html) * [NXEP 4 — Default random interface](nxeps/nxep-0004.html) --- # Releases — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Releases[#](#releases "Link to this heading") ============================================== We don’t use semantic versioning. The first number indicates that we have made a major API break (e.g., 1.x to 2.x), which has happened once and probably won’t happen again for some time. The point releases are new versions and may contain minor API breakage. Usually, this happens after a one cycle deprecation period. Warning Since we don’t normally make bug-fix only releases, it may not make sense for you to use `~=` as a pip version specifier. * [NetworkX 3.4.2](release_3.4.2.html) * [Bug Fixes](release_3.4.2.html#bug-fixes) * [Documentation](release_3.4.2.html#documentation) * [Maintenance](release_3.4.2.html#maintenance) * [Contributors](release_3.4.2.html#contributors) * [NetworkX 3.4.1](release_3.4.1.html) * [Maintenance](release_3.4.1.html#maintenance) * [Contributors](release_3.4.1.html#contributors) * [NetworkX 3.4](release_3.4.html) * [API Changes](release_3.4.html#api-changes) * [Enhancements](release_3.4.html#enhancements) * [Bug Fixes](release_3.4.html#bug-fixes) * [Documentation](release_3.4.html#documentation) * [Maintenance](release_3.4.html#maintenance) * [Other](release_3.4.html#other) * [Contributors](release_3.4.html#contributors) * [NetworkX 3.3](release_3.3.html) * [API Changes](release_3.3.html#api-changes) * [Enhancements](release_3.3.html#enhancements) * [Bug Fixes](release_3.3.html#bug-fixes) * [Documentation](release_3.3.html#documentation) * [Maintenance](release_3.3.html#maintenance) * [Contributors](release_3.3.html#contributors) * [NetworkX 3.2.1](release_3.2.1.html) * [API Changes](release_3.2.1.html#api-changes) * [Enhancements](release_3.2.1.html#enhancements) * [Bug Fixes](release_3.2.1.html#bug-fixes) * [Documentation](release_3.2.1.html#documentation) * [Maintenance](release_3.2.1.html#maintenance) * [Other](release_3.2.1.html#other) * [Contributors](release_3.2.1.html#contributors) * [NetworkX 3.2](release_3.2.html) * [Highlights](release_3.2.html#highlights) * [API Changes](release_3.2.html#api-changes) * [Enhancements](release_3.2.html#enhancements) * [Bug Fixes](release_3.2.html#bug-fixes) * [Documentation](release_3.2.html#documentation) * [Maintenance](release_3.2.html#maintenance) * [Other](release_3.2.html#other) * [Contributors](release_3.2.html#contributors) * [NetworkX 3.1](release_3.1.html) * [Highlights](release_3.1.html#highlights) * [Improvements](release_3.1.html#improvements) * [Deprecations](release_3.1.html#deprecations) * [Merged PRs](release_3.1.html#merged-prs) * [Contributors](release_3.1.html#contributors) * [NetworkX 3.0](release_3.0.html) * [Highlights](release_3.0.html#highlights) * [Improvements](release_3.0.html#improvements) * [API Changes](release_3.0.html#api-changes) * [Deprecations](release_3.0.html#deprecations) * [Merged PRs](release_3.0.html#merged-prs) * [Contributors](release_3.0.html#contributors) * [NetworkX 2.8.8](release_2.8.8.html) * [Highlights](release_2.8.8.html#highlights) * [Merged PRs](release_2.8.8.html#merged-prs) * [Contributors](release_2.8.8.html#contributors) * [NetworkX 2.8.7](release_2.8.7.html) * [Highlights](release_2.8.7.html#highlights) * [Merged PRs](release_2.8.7.html#merged-prs) * [Improvements](release_2.8.7.html#improvements) * [Contributors](release_2.8.7.html#contributors) * [NetworkX 2.8.6](release_2.8.6.html) * [Highlights](release_2.8.6.html#highlights) * [Merged PRs](release_2.8.6.html#merged-prs) * [Improvements](release_2.8.6.html#improvements) * [Contributors](release_2.8.6.html#contributors) * [NetworkX 2.8.5](release_2.8.5.html) * [Highlights](release_2.8.5.html#highlights) * [Merged PRs](release_2.8.5.html#merged-prs) * [Contributors](release_2.8.5.html#contributors) * [NetworkX 2.8.4](release_2.8.4.html) * [Highlights](release_2.8.4.html#highlights) * [Merged PRs](release_2.8.4.html#merged-prs) * [Contributors](release_2.8.4.html#contributors) * [NetworkX 2.8.3](release_2.8.3.html) * [Highlights](release_2.8.3.html#highlights) * [Merged PRs](release_2.8.3.html#merged-prs) * [Contributors](release_2.8.3.html#contributors) * [NetworkX 2.8.2](release_2.8.2.html) * [Highlights](release_2.8.2.html#highlights) * [Merged PRs](release_2.8.2.html#merged-prs) * [Contributors](release_2.8.2.html#contributors) * [NetworkX 2.8.1](release_2.8.1.html) * [Highlights](release_2.8.1.html#highlights) * [Improvements](release_2.8.1.html#improvements) * [Merged PRs](release_2.8.1.html#merged-prs) * [Contributors](release_2.8.1.html#contributors) * [NetworkX 2.8](release_2.8.html) * [Highlights](release_2.8.html#highlights) * [Improvements](release_2.8.html#improvements) * [API Changes](release_2.8.html#api-changes) * [Deprecations](release_2.8.html#deprecations) * [Merged PRs](release_2.8.html#merged-prs) * [Contributors](release_2.8.html#contributors) * [NetworkX 2.7.1](release_2.7.1.html) * [Merged PRs](release_2.7.1.html#merged-prs) * [Contributors](release_2.7.1.html#contributors) * [NetworkX 2.7](release_2.7.html) * [Highlights](release_2.7.html#highlights) * [GSoC PRs](release_2.7.html#gsoc-prs) * [Improvements](release_2.7.html#improvements) * [API Changes](release_2.7.html#api-changes) * [Deprecations](release_2.7.html#deprecations) * [Merged PRs](release_2.7.html#merged-prs) * [Contributors](release_2.7.html#contributors) * [NetworkX 2.6](release_2.6.html) * [Highlights](release_2.6.html#highlights) * [NXEPs](release_2.6.html#nxeps) * [Improvements](release_2.6.html#improvements) * [API Changes](release_2.6.html#api-changes) * [Deprecations](release_2.6.html#deprecations) * [Merged PRs](release_2.6.html#merged-prs) * [Contributors](release_2.6.html#contributors) * [NetworkX 2.5](release_2.5.html) * [Highlights](release_2.5.html#highlights) * [Improvements](release_2.5.html#improvements) * [API Changes](release_2.5.html#api-changes) * [Deprecations](release_2.5.html#deprecations) * [Merged PRs](release_2.5.html#merged-prs) * [Contributors](release_2.5.html#contributors) * [NetworkX 2.4](release_2.4.html) * [Highlights](release_2.4.html#highlights) * [Improvements](release_2.4.html#improvements) * [API Changes](release_2.4.html#api-changes) * [Deprecations](release_2.4.html#deprecations) * [Merged PRs](release_2.4.html#merged-prs) * [Contributors](release_2.4.html#contributors) * [NetworkX 2.3](release_2.3.html) * [Highlights](release_2.3.html#highlights) * [Improvements](release_2.3.html#improvements) * [API Changes](release_2.3.html#api-changes) * [Deprecations](release_2.3.html#deprecations) * [Contributors](release_2.3.html#contributors) * [NetworkX 2.2](release_2.2.html) * [Highlights](release_2.2.html#highlights) * [Improvements](release_2.2.html#improvements) * [API Changes](release_2.2.html#api-changes) * [Deprecations](release_2.2.html#deprecations) * [Contributors](release_2.2.html#contributors) * [NetworkX 2.1](release_2.1.html) * [Highlights](release_2.1.html#highlights) * [Improvements](release_2.1.html#improvements) * [API Changes](release_2.1.html#api-changes) * [Deprecations](release_2.1.html#deprecations) * [Contributors](release_2.1.html#contributors) * [Merged PRs](release_2.1.html#merged-prs) * [NetworkX 2.0](release_2.0.html) * [Highlights](release_2.0.html#highlights) * [API Changes](release_2.0.html#api-changes) * [Deprecations](release_2.0.html#deprecations) * [Contributors](release_2.0.html#contributors) * [Merged PRs](release_2.0.html#merged-prs) * [NetworkX 1.11](api_1.11.html) * [Highlights](api_1.11.html#highlights) * [NetworkX 1.10](api_1.10.html) * [Highlights](api_1.10.html#highlights) * [NetworkX 1.9](api_1.9.html) * [Highlights](api_1.9.html#highlights) * [Flow package](api_1.9.html#flow-package) * [Main changes](api_1.9.html#main-changes) * [Examples](api_1.9.html#examples) * [Connectivity package](api_1.9.html#connectivity-package) * [Other new functionalities](api_1.9.html#other-new-functionalities) * [Miscellaneous changes](api_1.9.html#miscellaneous-changes) * [NetworkX 1.8](api_1.8.html) * [Highlights](api_1.8.html#highlights) * [Bug fixes](api_1.8.html#bug-fixes) * [API changes](api_1.8.html#api-changes) * [NetworkX 1.7](api_1.7.html) * [Highlights](api_1.7.html#highlights) * [NetworkX 1.6](api_1.6.html) * [Highlights](api_1.6.html#highlights) * [NetworkX 1.5](api_1.5.html) * [Highlights](api_1.5.html#highlights) * [New features](api_1.5.html#new-features) * [Bug fixes](api_1.5.html#bug-fixes) * [NetworkX 1.4](api_1.4.html) * [New features](api_1.4.html#new-features) * [API changes](api_1.4.html#api-changes) * [Algorithms changed](api_1.4.html#algorithms-changed) * [Shortest path](api_1.4.html#shortest-path) * [NetworkX 1.0](api_1.0.html) * [New features](api_1.0.html#new-features) * [Examples](api_1.0.html#examples) * [Version numbering](api_1.0.html#version-numbering) * [Changes in base classes](api_1.0.html#changes-in-base-classes) * [Methods changed](api_1.0.html#methods-changed) * [Methods removed](api_1.0.html#methods-removed) * [Members removed](api_1.0.html#members-removed) * [Methods added](api_1.0.html#methods-added) * [Classes Removed](api_1.0.html#classes-removed) * [Additional functions/generators](api_1.0.html#additional-functions-generators) * [Converting your existing code to networkx-1.0](api_1.0.html#converting-your-existing-code-to-networkx-1-0) * [NetworkX 0.99](api_0.99.html) * [New features](api_0.99.html#new-features) * [Bug fixes](api_0.99.html#bug-fixes) * [Examples](api_0.99.html#examples) * [Changes in base classes](api_0.99.html#changes-in-base-classes) * [Methods changed](api_0.99.html#methods-changed) * [Methods removed](api_0.99.html#methods-removed) * [Methods added](api_0.99.html#methods-added) * [Other possible incompatibilities with existing code](api_0.99.html#other-possible-incompatibilities-with-existing-code) * [Imports](api_0.99.html#imports) * [Self-loops](api_0.99.html#self-loops) * [Copy](api_0.99.html#copy) * [prepare\_nbunch](api_0.99.html#prepare-nbunch) * [Converting your old code to Version 0.99](api_0.99.html#converting-your-old-code-to-version-0-99) * [Old Release Log](old_release_log.html) * [NetworkX 2.5](old_release_log.html#networkx-2-5) * [NetworkX 2.4](old_release_log.html#networkx-2-4) * [NetworkX 2.3](old_release_log.html#networkx-2-3) * [NetworkX 2.2](old_release_log.html#networkx-2-2) * [NetworkX 2.1](old_release_log.html#networkx-2-1) * [NetworkX 2.0](old_release_log.html#networkx-2-0) * [NetworkX 1.11](old_release_log.html#networkx-1-11) * [NetworkX 1.10](old_release_log.html#networkx-1-10) * [NetworkX 1.9.1](old_release_log.html#networkx-1-9-1) * [NetworkX 1.9](old_release_log.html#networkx-1-9) * [NetworkX 1.8.1](old_release_log.html#networkx-1-8-1) * [NetworkX 1.8](old_release_log.html#networkx-1-8) * [NetworkX 1.7](old_release_log.html#networkx-1-7) * [NetworkX 1.6](old_release_log.html#networkx-1-6) * [NetworkX 1.5](old_release_log.html#networkx-1-5) * [NetworkX 1.4](old_release_log.html#networkx-1-4) * [NetworkX 1.3](old_release_log.html#networkx-1-3) * [NetworkX 1.2](old_release_log.html#networkx-1-2) * [NetworkX 1.1](old_release_log.html#networkx-1-1) * [NetworkX 1.0.1](old_release_log.html#networkx-1-0-1) * [NetworkX 1.0](old_release_log.html#networkx-1-0) * [NetworkX 0.99](old_release_log.html#networkx-0-99) * [NetworkX 0.37](old_release_log.html#networkx-0-37) * [NetworkX 0.36](old_release_log.html#networkx-0-36) * [NetworkX 0.35.1](old_release_log.html#networkx-0-35-1) * [NetworkX 0.35](old_release_log.html#networkx-0-35) * [NetworkX 0.34](old_release_log.html#networkx-0-34) * [NetworkX 0.33](old_release_log.html#networkx-0-33) * [NetworkX 0.32](old_release_log.html#networkx-0-32) * [NetworkX 0.31](old_release_log.html#networkx-0-31) * [NetworkX 0.30](old_release_log.html#networkx-0-30) * [NetworkX 0.29](old_release_log.html#networkx-0-29) * [NetworkX 0.28](old_release_log.html#networkx-0-28) * [NetworkX 0.27](old_release_log.html#networkx-0-27) * [NetworkX 0.26](old_release_log.html#networkx-0-26) * [NetworkX 0.25](old_release_log.html#networkx-0-25) * [NetworkX 0.24](old_release_log.html#networkx-0-24) * [NetworkX 0.23](old_release_log.html#networkx-0-23) * [NetworkX 0.22](old_release_log.html#networkx-0-22) --- # Welcome to nx-guides! — NetworkX Notebooks [Skip to main content](#main-content) Back to top Ctrl+K [![NetworkX Notebooks - Home](_static/networkx_banner.svg) ![NetworkX Notebooks - Home](_static/networkx_banner.svg)](#) * [GitHub](https://github.com/networkx/nx-guides/ "GitHub") Search Ctrl+K * [Repository](https://github.com/networkx/nx-guides "Source repository") * [Suggest edit](https://github.com/networkx/nx-guides/edit/main/site/index.md "Suggest edit") * [Open issue](https://github.com/networkx/nx-guides/issues/new?title=Issue%20on%20page%20%2Findex.html&body=Your%20issue%20content%20here. "Open an issue") * [.md](_sources/index.md "Download source file") * .pdf Welcome to nx-guides! ===================== Contents -------- Welcome to nx-guides![#](#welcome-to-nx-guides "Link to this heading") ======================================================================= [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/networkx/nx-guides/main?urlpath=lab/tree/content) This site provides educational materials officially developed and curated by the NetworkX community. The goal of the repository is to provide high-quality educational resources for learning about network analysis and graph theory with NetworkX. Examples include: * Long-form narrative documentation, such as tutorials * In-depth examinations of common graph and network algorithms and their implementations in NetworkX * Demonstrations or domain-specific applications of NetworkX highlighting best-practices for network analysis. About[#](#about "Link to this heading") ---------------------------------------- The educational materials are in the form of [markdown-based Jupyter notebooks](https://myst-nb.readthedocs.io/en/latest/authoring/text-notebooks.html) , so everything is interactive! You can follow along yourself: 1. _on binder_, by clicking on the launch button at the top of this page, or the rocket icon in the upper-right corner of any of the pages, or 2. _locally_, by cloning the repository (see the octocat icon above) and running `jupyter notebook`. Contents[#](#contents "Link to this heading") ---------------------------------------------- * [Algorithms](content/algorithms/index.html) * [Graph Generators](content/generators/index.html) * [Facebook Network Analysis](content/exploratory_notebooks/facebook_notebook.html) * [Contributors Guide](content/contributing.html) Contents --- # NetworkX — NetworkX documentation ![Logo](_static/networkx_logo.svg) ================================== > NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. Software for complex networks ----------------------------- * Data structures for graphs, digraphs, and multigraphs * Many standard graph algorithms * Network structure and analysis measures * Generators for classic graphs, random graphs, and synthetic networks * Nodes can be "anything" (e.g., text, images, XML records) * Edges can hold arbitrary data (e.g., weights, time-series) * Open source [3-clause BSD license](https://raw.githubusercontent.com/networkx/networkx/master/LICENSE.txt) * Well tested with over 90% code coverage * Additional benefits from Python include fast prototyping, easy to teach, and multi-platform Contact ------- * [Mailing list](http://groups.google.com/group/networkx-discuss/) * [Issue tracker](https://github.com/networkx/networkx/issues) * [Source](https://github.com/networkx/networkx) Releases -------- #### Stable ([notes](https://networkx.org/documentation/stable/release/release_3.4.2.html) ) [3.4.2 — October 2024](http://pypi.python.org/pypi/networkx) [**Documentation**](https://networkx.org/documentation/stable/) #### Latest ([notes](https://networkx.org/documentation/latest/release/release_dev.html) ) [3.5 development](https://github.com/networkx/networkx) [**Documentation**](https://networkx.org/documentation/latest/) #### Archive --- # Introduction — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Introduction[#](#introduction "Link to this heading") ====================================================== The structure of NetworkX can be seen by the organization of its source code. The package provides classes for graph objects, generators to create standard graphs, IO routines for reading in existing datasets, algorithms to analyze the resulting networks and some basic drawing tools. Most of the NetworkX API is provided by functions which take a graph object as an argument. Methods of the graph object are limited to basic manipulation and reporting. This provides modularity of code and documentation. It also makes it easier for newcomers to learn about the package in stages. The source code for each module is meant to be easy to read and reading this Python code is actually a good way to learn more about network algorithms, but we have put a lot of effort into making the documentation sufficient and friendly. If you have suggestions or questions please contact us by joining the [NetworkX Google group](http://groups.google.com/group/networkx-discuss) . Classes are named using `CamelCase` (capital letters at the start of each word). functions, methods and variable names are `lower_case_underscore` (lowercase with an underscore representing a space between words). NetworkX Basics[#](#networkx-basics "Link to this heading") ------------------------------------------------------------ After starting Python, import the networkx module with (the recommended way) import networkx as nx To save repetition, in the documentation we assume that NetworkX has been imported this way. If importing networkx fails, it means that Python cannot find the installed module. Check your installation and your `PYTHONPATH`. The following basic graph types are provided as Python classes: [`Graph`](classes/graph.html#networkx.Graph "networkx.Graph") * This class implements an undirected graph. It ignores multiple edges between two nodes. It does allow self-loop edges between a node and itself. [`DiGraph`](classes/digraph.html#networkx.DiGraph "networkx.DiGraph") * Directed graphs, that is, graphs with directed edges. Provides operations common to directed graphs, (a subclass of Graph). [`MultiGraph`](classes/multigraph.html#networkx.MultiGraph "networkx.MultiGraph") * A flexible graph class that allows multiple undirected edges between pairs of nodes. The additional flexibility leads to some degradation in performance, though usually not significant. [`MultiDiGraph`](classes/multidigraph.html#networkx.MultiDiGraph "networkx.MultiDiGraph") * A directed version of a MultiGraph. Empty graph-like objects are created with G \= nx.Graph() G \= nx.DiGraph() G \= nx.MultiGraph() G \= nx.MultiDiGraph() All graph classes allow any [hashable](https://docs.python.org/3/glossary.html#term-hashable "(in Python v3.13)") object as a node. Hashable objects include strings, tuples, integers, and more. Arbitrary edge attributes such as weights and labels can be associated with an edge. The graph internal data structures are based on an adjacency list representation and implemented using Python [dictionary](glossary.html#term-dictionary) datastructures. The graph adjacency structure is implemented as a Python dictionary of dictionaries; the outer dictionary is keyed by nodes to values that are themselves dictionaries keyed by neighboring node to the edge attributes associated with that edge. This “dict-of-dicts” structure allows fast addition, deletion, and lookup of nodes and neighbors in large graphs. The underlying datastructure is accessed directly by methods (the programming interface “API”) in the class definitions. All functions, on the other hand, manipulate graph-like objects solely via those API methods and not by acting directly on the datastructure. This design allows for possible replacement of the ‘dicts-of-dicts’-based datastructure with an alternative datastructure that implements the same methods. Graphs[#](#graphs "Link to this heading") ------------------------------------------ The first choice to be made when using NetworkX is what type of graph object to use. A graph (network) is a collection of nodes together with a collection of edges that are pairs of nodes. Attributes are often associated with nodes and/or edges. NetworkX graph objects come in different flavors depending on two main properties of the network: > * Directed: Are the edges **directed**? Does the order of the edge pairs \\((u, v)\\) matter? A directed graph is specified by the “Di” prefix in the class name, e.g. [`DiGraph`](classes/digraph.html#networkx.DiGraph "networkx.DiGraph") > . We make this distinction because many classical graph properties are defined differently for directed graphs. > > * Multi-edges: Are multiple edges allowed between each pair of nodes? As you might imagine, multiple edges requires a different data structure, though clever users could design edge data attributes to support this functionality. We provide a standard data structure and interface for this type of graph using the prefix “Multi”, e.g., [`MultiGraph`](classes/multigraph.html#networkx.MultiGraph "networkx.MultiGraph") > . > The basic graph classes are named: [Graph](classes/graph.html) , [DiGraph](classes/digraph.html) , [MultiGraph](classes/multigraph.html) , and [MultiDiGraph](classes/multidigraph.html) ### Nodes and Edges[#](#nodes-and-edges "Link to this heading") The next choice you have to make when specifying a graph is what kinds of nodes and edges to use. If the topology of the network is all you care about then using integers or strings as the nodes makes sense and you need not worry about edge data. If you have a data structure already in place to describe nodes you can simply use that structure as your nodes provided it is [hashable](https://docs.python.org/3/glossary.html#term-hashable "(in Python v3.13)") . If it is not hashable you can use a unique identifier to represent the node and assign the data as a [node attribute](glossary.html#term-node-attribute) . Edges often have data associated with them. Arbitrary data can be associated with edges as an [edge attribute](glossary.html#term-edge-attribute) . If the data is numeric and the intent is to represent a _weighted_ graph then use the ‘weight’ keyword for the attribute. Some of the graph algorithms, such as Dijkstra’s shortest path algorithm, use this attribute name by default to get the weight for each edge. Attributes can be assigned to an edge by using keyword/value pairs when adding edges. You can use any keyword to name your attribute and can then query the edge data using that attribute keyword. Once you’ve decided how to encode the nodes and edges, and whether you have an undirected/directed graph with or without multiedges you are ready to build your network. Graph Creation[#](#graph-creation "Link to this heading") ---------------------------------------------------------- NetworkX graph objects can be created in one of three ways: * Graph generators—standard algorithms to create network topologies. * Importing data from preexisting (usually file) sources. * Adding edges and nodes explicitly. Explicit addition and removal of nodes/edges is the easiest to describe. Each graph object supplies methods to manipulate the graph. For example, G \= nx.Graph() G.add\_edge(1, 2) \# default edge data=1 G.add\_edge(2, 3, weight\=0.9) \# specify edge data Edge attributes can be anything: import math G.add\_edge('y', 'x', function\=math.cos) G.add\_node(math.cos) \# any hashable can be a node You can add many edges at one time: elist \= \[(1, 2), (2, 3), (1, 4), (4, 2)\] G.add\_edges\_from(elist) elist \= \[('a', 'b', 5.0), ('b', 'c', 3.0), ('a', 'c', 1.0), ('c', 'd', 7.3)\] G.add\_weighted\_edges\_from(elist) See the [Tutorial](../tutorial.html) for more examples. Some basic graph operations such as union and intersection are described in the [operators module](algorithms/operators.html#operators) documentation. Graph generators such as [`binomial_graph()`](generated/networkx.generators.random_graphs.binomial_graph.html#networkx.generators.random_graphs.binomial_graph "networkx.generators.random_graphs.binomial_graph") and [`erdos_renyi_graph()`](generated/networkx.generators.random_graphs.erdos_renyi_graph.html#networkx.generators.random_graphs.erdos_renyi_graph "networkx.generators.random_graphs.erdos_renyi_graph") are provided in the [graph generators](generators.html#generators) subpackage. For importing network data from formats such as GML, GraphML, edge list text files see the [reading and writing graphs](readwrite/index.html#readwrite) subpackage. Graph Reporting[#](#graph-reporting "Link to this heading") ------------------------------------------------------------ Class views provide basic reporting of nodes, neighbors, edges and degree. These views provide iteration over the properties as well as membership queries and data attribute lookup. The views refer to the graph data structure so changes to the graph are reflected in the views. This is analogous to dictionary views in Python 3. If you want to change the graph while iterating you will need to use e.g. `for e in list(G.edges):`. The views provide set-like operations, e.g. union and intersection, as well as dict-like lookup and iteration of the data attributes using `G.edges[u, v]['color']` and `for e, datadict in G.edges.items():`. Methods `G.edges.items()` and `G.edges.values()` are familiar from python dicts. In addition `G.edges.data()` provides specific attribute iteration e.g. `for e, e_color in G.edges.data('color'):`. The basic graph relationship of an edge can be obtained in two ways. One can look for neighbors of a node or one can look for edges. We jokingly refer to people who focus on nodes/neighbors as node-centric and people who focus on edges as edge-centric. The designers of NetworkX tend to be node-centric and view edges as a relationship between nodes. You can see this by our choice of lookup notation like `G[u]` providing neighbors (adjacency) while edge lookup is `G.edges[u, v]`. Most data structures for sparse graphs are essentially adjacency lists and so fit this perspective. In the end, of course, it doesn’t really matter which way you examine the graph. `G.edges` removes duplicate representations of undirected edges while neighbor reporting across all nodes will naturally report both directions. Any properties that are more complicated than edges, neighbors and degree are provided by functions. For example `nx.triangles(G, n)` gives the number of triangles which include node n as a vertex. These functions are grouped in the code and documentation under the term [algorithms](algorithms/index.html#algorithms) . Algorithms[#](#algorithms "Link to this heading") -------------------------------------------------- A number of graph algorithms are provided with NetworkX. These include shortest path, and breadth first search (see [traversal](algorithms/traversal.html#traversal) ), clustering and isomorphism algorithms and others. There are many that we have not developed yet too. If you implement a graph algorithm that might be useful for others please let us know through the [NetworkX Google group](http://groups.google.com/group/networkx-discuss) or the GitHub [Developer Zone](https://github.com/networkx/networkx) . As an example here is code to use Dijkstra’s algorithm to find the shortest weighted path: G \= nx.Graph() e \= \[('a', 'b', 0.3), ('b', 'c', 0.9), ('a', 'c', 0.5), ('c', 'd', 1.2)\] G.add\_weighted\_edges\_from(e) print(nx.dijkstra\_path(G, 'a', 'd')) \['a', 'c', 'd'\] Drawing[#](#drawing "Link to this heading") -------------------------------------------- While NetworkX is not designed as a network drawing tool, we provide a simple interface to drawing packages and some simple layout algorithms. We interface to the excellent Graphviz layout tools like dot and neato with the (suggested) pygraphviz package or the pydot interface. Drawing can be done using external programs or the Matplotlib Python package. Interactive GUI interfaces are possible, though not provided. The drawing tools are provided in the module [drawing](drawing.html#drawing) . The basic drawing functions essentially place the nodes on a scatterplot using the positions you provide via a dictionary or the positions are computed with a layout function. The edges are lines between those dots. import matplotlib.pyplot as plt G \= nx.cubical\_graph() subax1 \= plt.subplot(121) nx.draw(G) \# default spring\_layout subax2 \= plt.subplot(122) nx.draw(G, pos\=nx.circular\_layout(G), node\_color\='r', edge\_color\='b') ![../_images/94c232c7aafe07eab83385ae4d74c33dc1341ff3a7004766a43444e935e60e2c.png](../_images/94c232c7aafe07eab83385ae4d74c33dc1341ff3a7004766a43444e935e60e2c.png) See the [examples](../auto_examples/index.html) for more ideas. Data Structure[#](#data-structure "Link to this heading") ---------------------------------------------------------- NetworkX uses a “dictionary of dictionaries of dictionaries” as the basic network data structure. This allows fast lookup with reasonable storage for large sparse networks. The keys are nodes so `G[u]` returns an adjacency dictionary keyed by neighbor to the edge attribute dictionary. A view of the adjacency data structure is provided by the dict-like object `G.adj` as e.g. `for node, nbrsdict in G.adj.items():`. The expression `G[u][v]` returns the edge attribute dictionary itself. A dictionary of lists would have also been possible, but not allow fast edge detection nor convenient storage of edge data. Advantages of dict-of-dicts-of-dicts data structure: * Find edges and remove edges with two dictionary look-ups. * Prefer to “lists” because of fast lookup with sparse storage. * Prefer to “sets” since data can be attached to edge. * `G[u][v]` returns the edge attribute dictionary. * `n in G` tests if node `n` is in graph `G`. * `for n in G:` iterates through the graph. * `for nbr in G[n]:` iterates through neighbors. As an example, here is a representation of an undirected graph with the edges \\((A, B)\\) and \\((B, C)\\). G \= nx.Graph() G.add\_edge('A', 'B') G.add\_edge('B', 'C') print(G.adj) {'A': {'B': {}}, 'B': {'A': {}, 'C': {}}, 'C': {'B': {}}} The data structure gets morphed slightly for each base graph class. For DiGraph two dict-of-dicts-of-dicts structures are provided, one for successors (`G.succ`) and one for predecessors (`G.pred`). For MultiGraph/MultiDiGraph we use a dict-of-dicts-of-dicts-of-dicts [\[1\]](#turtles) where the third dictionary is keyed by an edge key identifier to the fourth dictionary which contains the edge attributes for that edge between the two nodes. Graphs provide two interfaces to the edge data attributes: adjacency and edges. So `G[u][v]['width']` is the same as `G.edges[u, v]['width']`. G \= nx.Graph() G.add\_edge(1, 2, color\='red', weight\=0.84, size\=300) print(G\[1\]\[2\]\['size'\]) print(G.edges\[1, 2\]\['color'\]) 300 red Footnotes * * * On this page --- # Algorithms — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Algorithms[#](#algorithms "Link to this heading") ================================================== * [Approximations and Heuristics](approximation.html) * [Connectivity](approximation.html#module-networkx.algorithms.approximation.connectivity) * [K-components](approximation.html#module-networkx.algorithms.approximation.kcomponents) * [Clique](approximation.html#module-networkx.algorithms.approximation.clique) * [Clustering](approximation.html#module-networkx.algorithms.approximation.clustering_coefficient) * [Distance Measures](approximation.html#module-networkx.algorithms.approximation.distance_measures) * [Dominating Set](approximation.html#module-networkx.algorithms.approximation.dominating_set) * [Matching](approximation.html#module-networkx.algorithms.approximation.matching) * [Ramsey](approximation.html#module-networkx.algorithms.approximation.ramsey) * [Steiner Tree](approximation.html#module-networkx.algorithms.approximation.steinertree) * [Traveling Salesman](approximation.html#module-networkx.algorithms.approximation.traveling_salesman) * [Treewidth](approximation.html#module-networkx.algorithms.approximation.treewidth) * [Vertex Cover](approximation.html#module-networkx.algorithms.approximation.vertex_cover) * [Max Cut](approximation.html#module-networkx.algorithms.approximation.maxcut) * [Assortativity](assortativity.html) * [Assortativity](assortativity.html#networkx-algorithms-assortativity-correlation) * [Average neighbor degree](assortativity.html#average-neighbor-degree) * [Average degree connectivity](assortativity.html#average-degree-connectivity) * [Mixing](assortativity.html#mixing) * [Pairs](assortativity.html#pairs) * [Asteroidal](asteroidal.html) * [is\_at\_free](generated/networkx.algorithms.asteroidal.is_at_free.html) * [find\_asteroidal\_triple](generated/networkx.algorithms.asteroidal.find_asteroidal_triple.html) * [Bipartite](bipartite.html) * [Basic functions](bipartite.html#module-networkx.algorithms.bipartite.basic) * [Edgelist](bipartite.html#module-networkx.algorithms.bipartite.edgelist) * [Matching](bipartite.html#module-networkx.algorithms.bipartite.matching) * [Matrix](bipartite.html#module-networkx.algorithms.bipartite.matrix) * [Projections](bipartite.html#module-networkx.algorithms.bipartite.projection) * [Spectral](bipartite.html#module-networkx.algorithms.bipartite.spectral) * [Clustering](bipartite.html#module-networkx.algorithms.bipartite.cluster) * [Redundancy](bipartite.html#module-networkx.algorithms.bipartite.redundancy) * [Centrality](bipartite.html#module-networkx.algorithms.bipartite.centrality) * [Generators](bipartite.html#module-networkx.algorithms.bipartite.generators) * [Covering](bipartite.html#module-networkx.algorithms.bipartite.covering) * [Extendability](bipartite.html#module-networkx.algorithms.bipartite.extendability) * [Boundary](boundary.html) * [edge\_boundary](generated/networkx.algorithms.boundary.edge_boundary.html) * [node\_boundary](generated/networkx.algorithms.boundary.node_boundary.html) * [Bridges](bridges.html) * [bridges](generated/networkx.algorithms.bridges.bridges.html) * [has\_bridges](generated/networkx.algorithms.bridges.has_bridges.html) * [local\_bridges](generated/networkx.algorithms.bridges.local_bridges.html) * [Broadcasting](broadcasting.html) * [tree\_broadcast\_center](generated/networkx.algorithms.broadcasting.tree_broadcast_center.html) * [tree\_broadcast\_time](generated/networkx.algorithms.broadcasting.tree_broadcast_time.html) * [Centrality](centrality.html) * [Degree](centrality.html#degree) * [Eigenvector](centrality.html#eigenvector) * [Closeness](centrality.html#closeness) * [Current Flow Closeness](centrality.html#current-flow-closeness) * [(Shortest Path) Betweenness](centrality.html#shortest-path-betweenness) * [Current Flow Betweenness](centrality.html#current-flow-betweenness) * [Communicability Betweenness](centrality.html#communicability-betweenness) * [Group Centrality](centrality.html#group-centrality) * [Load](centrality.html#load) * [Subgraph](centrality.html#subgraph) * [Harmonic Centrality](centrality.html#harmonic-centrality) * [Dispersion](centrality.html#dispersion) * [Reaching](centrality.html#reaching) * [Percolation](centrality.html#percolation) * [Second Order Centrality](centrality.html#second-order-centrality) * [Trophic](centrality.html#trophic) * [VoteRank](centrality.html#voterank) * [Laplacian](centrality.html#laplacian) * [Chains](chains.html) * [chain\_decomposition](generated/networkx.algorithms.chains.chain_decomposition.html) * [Chordal](chordal.html) * [is\_chordal](generated/networkx.algorithms.chordal.is_chordal.html) * [chordal\_graph\_cliques](generated/networkx.algorithms.chordal.chordal_graph_cliques.html) * [chordal\_graph\_treewidth](generated/networkx.algorithms.chordal.chordal_graph_treewidth.html) * [complete\_to\_chordal\_graph](generated/networkx.algorithms.chordal.complete_to_chordal_graph.html) * [find\_induced\_nodes](generated/networkx.algorithms.chordal.find_induced_nodes.html) * [Clique](clique.html) * [enumerate\_all\_cliques](generated/networkx.algorithms.clique.enumerate_all_cliques.html) * [find\_cliques](generated/networkx.algorithms.clique.find_cliques.html) * [find\_cliques\_recursive](generated/networkx.algorithms.clique.find_cliques_recursive.html) * [make\_max\_clique\_graph](generated/networkx.algorithms.clique.make_max_clique_graph.html) * [make\_clique\_bipartite](generated/networkx.algorithms.clique.make_clique_bipartite.html) * [node\_clique\_number](generated/networkx.algorithms.clique.node_clique_number.html) * [number\_of\_cliques](generated/networkx.algorithms.clique.number_of_cliques.html) * [max\_weight\_clique](generated/networkx.algorithms.clique.max_weight_clique.html) * [Clustering](clustering.html) * [triangles](generated/networkx.algorithms.cluster.triangles.html) * [transitivity](generated/networkx.algorithms.cluster.transitivity.html) * [clustering](generated/networkx.algorithms.cluster.clustering.html) * [average\_clustering](generated/networkx.algorithms.cluster.average_clustering.html) * [square\_clustering](generated/networkx.algorithms.cluster.square_clustering.html) * [generalized\_degree](generated/networkx.algorithms.cluster.generalized_degree.html) * [Coloring](coloring.html) * [greedy\_color](generated/networkx.algorithms.coloring.greedy_color.html) * [equitable\_color](generated/networkx.algorithms.coloring.equitable_color.html) * [strategy\_connected\_sequential](generated/networkx.algorithms.coloring.strategy_connected_sequential.html) * [strategy\_connected\_sequential\_dfs](generated/networkx.algorithms.coloring.strategy_connected_sequential_dfs.html) * [strategy\_connected\_sequential\_bfs](generated/networkx.algorithms.coloring.strategy_connected_sequential_bfs.html) * [strategy\_independent\_set](generated/networkx.algorithms.coloring.strategy_independent_set.html) * [strategy\_largest\_first](generated/networkx.algorithms.coloring.strategy_largest_first.html) * [strategy\_random\_sequential](generated/networkx.algorithms.coloring.strategy_random_sequential.html) * [strategy\_saturation\_largest\_first](generated/networkx.algorithms.coloring.strategy_saturation_largest_first.html) * [strategy\_smallest\_last](generated/networkx.algorithms.coloring.strategy_smallest_last.html) * [Communicability](communicability_alg.html) * [communicability](generated/networkx.algorithms.communicability_alg.communicability.html) * [communicability\_exp](generated/networkx.algorithms.communicability_alg.communicability_exp.html) * [Communities](community.html) * [Bipartitions](community.html#module-networkx.algorithms.community.kernighan_lin) * [Divisive Communities](community.html#module-networkx.algorithms.community.divisive) * [K-Clique](community.html#module-networkx.algorithms.community.kclique) * [Modularity-based communities](community.html#module-networkx.algorithms.community.modularity_max) * [Tree partitioning](community.html#module-networkx.algorithms.community.lukes) * [Label propagation](community.html#module-networkx.algorithms.community.label_propagation) * [Louvain Community Detection](community.html#module-networkx.algorithms.community.louvain) * [Fluid Communities](community.html#module-networkx.algorithms.community.asyn_fluid) * [Measuring partitions](community.html#module-networkx.algorithms.community.quality) * [Partitions via centrality measures](community.html#module-networkx.algorithms.community.centrality) * [Validating partitions](community.html#module-networkx.algorithms.community.community_utils) * [Components](component.html) * [Connectivity](component.html#connectivity) * [Strong connectivity](component.html#strong-connectivity) * [Weak connectivity](component.html#weak-connectivity) * [Attracting components](component.html#attracting-components) * [Biconnected components](component.html#biconnected-components) * [Semiconnectedness](component.html#semiconnectedness) * [Connectivity](connectivity.html) * [Edge-augmentation](connectivity.html#module-networkx.algorithms.connectivity.edge_augmentation) * [K-edge-components](connectivity.html#module-networkx.algorithms.connectivity.edge_kcomponents) * [K-node-components](connectivity.html#module-networkx.algorithms.connectivity.kcomponents) * [K-node-cutsets](connectivity.html#module-networkx.algorithms.connectivity.kcutsets) * [Flow-based disjoint paths](connectivity.html#module-networkx.algorithms.connectivity.disjoint_paths) * [Flow-based Connectivity](connectivity.html#module-networkx.algorithms.connectivity.connectivity) * [Flow-based Minimum Cuts](connectivity.html#module-networkx.algorithms.connectivity.cuts) * [Stoer-Wagner minimum cut](connectivity.html#module-networkx.algorithms.connectivity.stoerwagner) * [Utils for flow-based connectivity](connectivity.html#module-networkx.algorithms.connectivity.utils) * [Cores](core.html) * [core\_number](generated/networkx.algorithms.core.core_number.html) * [k\_core](generated/networkx.algorithms.core.k_core.html) * [k\_shell](generated/networkx.algorithms.core.k_shell.html) * [k\_crust](generated/networkx.algorithms.core.k_crust.html) * [k\_corona](generated/networkx.algorithms.core.k_corona.html) * [k\_truss](generated/networkx.algorithms.core.k_truss.html) * [onion\_layers](generated/networkx.algorithms.core.onion_layers.html) * [Covering](covering.html) * [min\_edge\_cover](generated/networkx.algorithms.covering.min_edge_cover.html) * [is\_edge\_cover](generated/networkx.algorithms.covering.is_edge_cover.html) * [Cycles](cycles.html) * [cycle\_basis](generated/networkx.algorithms.cycles.cycle_basis.html) * [simple\_cycles](generated/networkx.algorithms.cycles.simple_cycles.html) * [recursive\_simple\_cycles](generated/networkx.algorithms.cycles.recursive_simple_cycles.html) * [find\_cycle](generated/networkx.algorithms.cycles.find_cycle.html) * [minimum\_cycle\_basis](generated/networkx.algorithms.cycles.minimum_cycle_basis.html) * [chordless\_cycles](generated/networkx.algorithms.cycles.chordless_cycles.html) * [girth](generated/networkx.algorithms.cycles.girth.html) * [Cuts](cuts.html) * [boundary\_expansion](generated/networkx.algorithms.cuts.boundary_expansion.html) * [conductance](generated/networkx.algorithms.cuts.conductance.html) * [cut\_size](generated/networkx.algorithms.cuts.cut_size.html) * [edge\_expansion](generated/networkx.algorithms.cuts.edge_expansion.html) * [mixing\_expansion](generated/networkx.algorithms.cuts.mixing_expansion.html) * [node\_expansion](generated/networkx.algorithms.cuts.node_expansion.html) * [normalized\_cut\_size](generated/networkx.algorithms.cuts.normalized_cut_size.html) * [volume](generated/networkx.algorithms.cuts.volume.html) * [D-Separation](d_separation.html) * [D-separators](d_separation.html#d-separators) * [Illustration of D-separation with examples](d_separation.html#illustration-of-d-separation-with-examples) * [D-separation and its applications in probability](d_separation.html#d-separation-and-its-applications-in-probability) * [Examples](d_separation.html#examples) * [References](d_separation.html#references) * [is\_d\_separator](generated/networkx.algorithms.d_separation.is_d_separator.html) * [is\_minimal\_d\_separator](generated/networkx.algorithms.d_separation.is_minimal_d_separator.html) * [find\_minimal\_d\_separator](generated/networkx.algorithms.d_separation.find_minimal_d_separator.html) * [Directed Acyclic Graphs](dag.html) * [ancestors](generated/networkx.algorithms.dag.ancestors.html) * [descendants](generated/networkx.algorithms.dag.descendants.html) * [topological\_sort](generated/networkx.algorithms.dag.topological_sort.html) * [topological\_generations](generated/networkx.algorithms.dag.topological_generations.html) * [all\_topological\_sorts](generated/networkx.algorithms.dag.all_topological_sorts.html) * [lexicographical\_topological\_sort](generated/networkx.algorithms.dag.lexicographical_topological_sort.html) * [is\_directed\_acyclic\_graph](generated/networkx.algorithms.dag.is_directed_acyclic_graph.html) * [is\_aperiodic](generated/networkx.algorithms.dag.is_aperiodic.html) * [transitive\_closure](generated/networkx.algorithms.dag.transitive_closure.html) * [transitive\_closure\_dag](generated/networkx.algorithms.dag.transitive_closure_dag.html) * [transitive\_reduction](generated/networkx.algorithms.dag.transitive_reduction.html) * [antichains](generated/networkx.algorithms.dag.antichains.html) * [dag\_longest\_path](generated/networkx.algorithms.dag.dag_longest_path.html) * [dag\_longest\_path\_length](generated/networkx.algorithms.dag.dag_longest_path_length.html) * [dag\_to\_branching](generated/networkx.algorithms.dag.dag_to_branching.html) * [compute\_v\_structures](generated/networkx.algorithms.dag.compute_v_structures.html) * [colliders](generated/networkx.algorithms.dag.colliders.html) * [v\_structures](generated/networkx.algorithms.dag.v_structures.html) * [Distance Measures](distance_measures.html) * [barycenter](generated/networkx.algorithms.distance_measures.barycenter.html) * [center](generated/networkx.algorithms.distance_measures.center.html) * [diameter](generated/networkx.algorithms.distance_measures.diameter.html) * [harmonic\_diameter](generated/networkx.algorithms.distance_measures.harmonic_diameter.html) * [eccentricity](generated/networkx.algorithms.distance_measures.eccentricity.html) * [effective\_graph\_resistance](generated/networkx.algorithms.distance_measures.effective_graph_resistance.html) * [kemeny\_constant](generated/networkx.algorithms.distance_measures.kemeny_constant.html) * [periphery](generated/networkx.algorithms.distance_measures.periphery.html) * [radius](generated/networkx.algorithms.distance_measures.radius.html) * [resistance\_distance](generated/networkx.algorithms.distance_measures.resistance_distance.html) * [Distance-Regular Graphs](distance_regular.html) * [is\_distance\_regular](generated/networkx.algorithms.distance_regular.is_distance_regular.html) * [is\_strongly\_regular](generated/networkx.algorithms.distance_regular.is_strongly_regular.html) * [intersection\_array](generated/networkx.algorithms.distance_regular.intersection_array.html) * [global\_parameters](generated/networkx.algorithms.distance_regular.global_parameters.html) * [Dominance](dominance.html) * [immediate\_dominators](generated/networkx.algorithms.dominance.immediate_dominators.html) * [dominance\_frontiers](generated/networkx.algorithms.dominance.dominance_frontiers.html) * [Dominating Sets](dominating.html) * [dominating\_set](generated/networkx.algorithms.dominating.dominating_set.html) * [is\_dominating\_set](generated/networkx.algorithms.dominating.is_dominating_set.html) * [Efficiency](efficiency_measures.html) * [efficiency](generated/networkx.algorithms.efficiency_measures.efficiency.html) * [local\_efficiency](generated/networkx.algorithms.efficiency_measures.local_efficiency.html) * [global\_efficiency](generated/networkx.algorithms.efficiency_measures.global_efficiency.html) * [Eulerian](euler.html) * [is\_eulerian](generated/networkx.algorithms.euler.is_eulerian.html) * [eulerian\_circuit](generated/networkx.algorithms.euler.eulerian_circuit.html) * [eulerize](generated/networkx.algorithms.euler.eulerize.html) * [is\_semieulerian](generated/networkx.algorithms.euler.is_semieulerian.html) * [has\_eulerian\_path](generated/networkx.algorithms.euler.has_eulerian_path.html) * [eulerian\_path](generated/networkx.algorithms.euler.eulerian_path.html) * [Flows](flow.html) * [Maximum Flow](flow.html#maximum-flow) * [Edmonds-Karp](flow.html#edmonds-karp) * [Shortest Augmenting Path](flow.html#shortest-augmenting-path) * [Preflow-Push](flow.html#preflow-push) * [Dinitz](flow.html#dinitz) * [Boykov-Kolmogorov](flow.html#boykov-kolmogorov) * [Gomory-Hu Tree](flow.html#gomory-hu-tree) * [Utils](flow.html#utils) * [Network Simplex](flow.html#network-simplex) * [Capacity Scaling Minimum Cost Flow](flow.html#capacity-scaling-minimum-cost-flow) * [Graph Hashing](graph_hashing.html) * [weisfeiler\_lehman\_graph\_hash](generated/networkx.algorithms.graph_hashing.weisfeiler_lehman_graph_hash.html) * [weisfeiler\_lehman\_subgraph\_hashes](generated/networkx.algorithms.graph_hashing.weisfeiler_lehman_subgraph_hashes.html) * [Graphical degree sequence](graphical.html) * [is\_graphical](generated/networkx.algorithms.graphical.is_graphical.html) * [is\_digraphical](generated/networkx.algorithms.graphical.is_digraphical.html) * [is\_multigraphical](generated/networkx.algorithms.graphical.is_multigraphical.html) * [is\_pseudographical](generated/networkx.algorithms.graphical.is_pseudographical.html) * [is\_valid\_degree\_sequence\_havel\_hakimi](generated/networkx.algorithms.graphical.is_valid_degree_sequence_havel_hakimi.html) * [is\_valid\_degree\_sequence\_erdos\_gallai](generated/networkx.algorithms.graphical.is_valid_degree_sequence_erdos_gallai.html) * [Hierarchy](hierarchy.html) * [flow\_hierarchy](generated/networkx.algorithms.hierarchy.flow_hierarchy.html) * [Hybrid](hybrid.html) * [kl\_connected\_subgraph](generated/networkx.algorithms.hybrid.kl_connected_subgraph.html) * [is\_kl\_connected](generated/networkx.algorithms.hybrid.is_kl_connected.html) * [Isolates](isolates.html) * [is\_isolate](generated/networkx.algorithms.isolate.is_isolate.html) * [isolates](generated/networkx.algorithms.isolate.isolates.html) * [number\_of\_isolates](generated/networkx.algorithms.isolate.number_of_isolates.html) * [Isomorphism](isomorphism.html) * [is\_isomorphic](generated/networkx.algorithms.isomorphism.is_isomorphic.html) * [could\_be\_isomorphic](generated/networkx.algorithms.isomorphism.could_be_isomorphic.html) * [fast\_could\_be\_isomorphic](generated/networkx.algorithms.isomorphism.fast_could_be_isomorphic.html) * [faster\_could\_be\_isomorphic](generated/networkx.algorithms.isomorphism.faster_could_be_isomorphic.html) * [VF2++](isomorphism.html#module-networkx.algorithms.isomorphism.vf2pp) * [Tree Isomorphism](isomorphism.html#module-networkx.algorithms.isomorphism.tree_isomorphism) * [Advanced Interfaces](isomorphism.html#advanced-interfaces) * [Link Analysis](link_analysis.html) * [PageRank](link_analysis.html#module-networkx.algorithms.link_analysis.pagerank_alg) * [Hits](link_analysis.html#module-networkx.algorithms.link_analysis.hits_alg) * [Link Prediction](link_prediction.html) * [resource\_allocation\_index](generated/networkx.algorithms.link_prediction.resource_allocation_index.html) * [jaccard\_coefficient](generated/networkx.algorithms.link_prediction.jaccard_coefficient.html) * [adamic\_adar\_index](generated/networkx.algorithms.link_prediction.adamic_adar_index.html) * [preferential\_attachment](generated/networkx.algorithms.link_prediction.preferential_attachment.html) * [cn\_soundarajan\_hopcroft](generated/networkx.algorithms.link_prediction.cn_soundarajan_hopcroft.html) * [ra\_index\_soundarajan\_hopcroft](generated/networkx.algorithms.link_prediction.ra_index_soundarajan_hopcroft.html) * [within\_inter\_cluster](generated/networkx.algorithms.link_prediction.within_inter_cluster.html) * [common\_neighbor\_centrality](generated/networkx.algorithms.link_prediction.common_neighbor_centrality.html) * [Lowest Common Ancestor](lowest_common_ancestors.html) * [all\_pairs\_lowest\_common\_ancestor](generated/networkx.algorithms.lowest_common_ancestors.all_pairs_lowest_common_ancestor.html) * [tree\_all\_pairs\_lowest\_common\_ancestor](generated/networkx.algorithms.lowest_common_ancestors.tree_all_pairs_lowest_common_ancestor.html) * [lowest\_common\_ancestor](generated/networkx.algorithms.lowest_common_ancestors.lowest_common_ancestor.html) * [Matching](matching.html) * [is\_matching](generated/networkx.algorithms.matching.is_matching.html) * [is\_maximal\_matching](generated/networkx.algorithms.matching.is_maximal_matching.html) * [is\_perfect\_matching](generated/networkx.algorithms.matching.is_perfect_matching.html) * [maximal\_matching](generated/networkx.algorithms.matching.maximal_matching.html) * [max\_weight\_matching](generated/networkx.algorithms.matching.max_weight_matching.html) * [min\_weight\_matching](generated/networkx.algorithms.matching.min_weight_matching.html) * [Minors](minors.html) * [References](minors.html#references) * [contracted\_edge](generated/networkx.algorithms.minors.contracted_edge.html) * [contracted\_nodes](generated/networkx.algorithms.minors.contracted_nodes.html) * [identified\_nodes](generated/networkx.algorithms.minors.identified_nodes.html) * [equivalence\_classes](generated/networkx.algorithms.minors.equivalence_classes.html) * [quotient\_graph](generated/networkx.algorithms.minors.quotient_graph.html) * [Maximal independent set](mis.html) * [maximal\_independent\_set](generated/networkx.algorithms.mis.maximal_independent_set.html) * [non-randomness](non_randomness.html) * [non\_randomness](generated/networkx.algorithms.non_randomness.non_randomness.html) * [Moral](moral.html) * [moral\_graph](generated/networkx.algorithms.moral.moral_graph.html) * [Node Classification](node_classification.html) * [References](node_classification.html#references) * [harmonic\_function](generated/networkx.algorithms.node_classification.harmonic_function.html) * [local\_and\_global\_consistency](generated/networkx.algorithms.node_classification.local_and_global_consistency.html) * [Operators](operators.html) * [complement](generated/networkx.algorithms.operators.unary.complement.html) * [reverse](generated/networkx.algorithms.operators.unary.reverse.html) * [compose](generated/networkx.algorithms.operators.binary.compose.html) * [union](generated/networkx.algorithms.operators.binary.union.html) * [disjoint\_union](generated/networkx.algorithms.operators.binary.disjoint_union.html) * [intersection](generated/networkx.algorithms.operators.binary.intersection.html) * [difference](generated/networkx.algorithms.operators.binary.difference.html) * [symmetric\_difference](generated/networkx.algorithms.operators.binary.symmetric_difference.html) * [full\_join](generated/networkx.algorithms.operators.binary.full_join.html) * [compose\_all](generated/networkx.algorithms.operators.all.compose_all.html) * [union\_all](generated/networkx.algorithms.operators.all.union_all.html) * [disjoint\_union\_all](generated/networkx.algorithms.operators.all.disjoint_union_all.html) * [intersection\_all](generated/networkx.algorithms.operators.all.intersection_all.html) * [cartesian\_product](generated/networkx.algorithms.operators.product.cartesian_product.html) * [lexicographic\_product](generated/networkx.algorithms.operators.product.lexicographic_product.html) * [rooted\_product](generated/networkx.algorithms.operators.product.rooted_product.html) * [strong\_product](generated/networkx.algorithms.operators.product.strong_product.html) * [tensor\_product](generated/networkx.algorithms.operators.product.tensor_product.html) * [power](generated/networkx.algorithms.operators.product.power.html) * [corona\_product](generated/networkx.algorithms.operators.product.corona_product.html) * [modular\_product](generated/networkx.algorithms.operators.product.modular_product.html) * [Planarity](planarity.html) * [check\_planarity](generated/networkx.algorithms.planarity.check_planarity.html) * [is\_planar](generated/networkx.algorithms.planarity.is_planar.html) * [networkx.algorithms.planarity.PlanarEmbedding](generated/networkx.algorithms.planarity.PlanarEmbedding.html) * [Planar Drawing](planar_drawing.html) * [combinatorial\_embedding\_to\_pos](generated/networkx.algorithms.planar_drawing.combinatorial_embedding_to_pos.html) * [Graph Polynomials](polynomials.html) * [tutte\_polynomial](generated/networkx.algorithms.polynomials.tutte_polynomial.html) * [chromatic\_polynomial](generated/networkx.algorithms.polynomials.chromatic_polynomial.html) * [Reciprocity](reciprocity.html) * [reciprocity](generated/networkx.algorithms.reciprocity.reciprocity.html) * [overall\_reciprocity](generated/networkx.algorithms.reciprocity.overall_reciprocity.html) * [Regular](regular.html) * [is\_regular](generated/networkx.algorithms.regular.is_regular.html) * [is\_k\_regular](generated/networkx.algorithms.regular.is_k_regular.html) * [k\_factor](generated/networkx.algorithms.regular.k_factor.html) * [Rich Club](rich_club.html) * [rich\_club\_coefficient](generated/networkx.algorithms.richclub.rich_club_coefficient.html) * [Shortest Paths](shortest_paths.html) * [shortest\_path](generated/networkx.algorithms.shortest_paths.generic.shortest_path.html) * [all\_shortest\_paths](generated/networkx.algorithms.shortest_paths.generic.all_shortest_paths.html) * [all\_pairs\_all\_shortest\_paths](generated/networkx.algorithms.shortest_paths.generic.all_pairs_all_shortest_paths.html) * [single\_source\_all\_shortest\_paths](generated/networkx.algorithms.shortest_paths.generic.single_source_all_shortest_paths.html) * [shortest\_path\_length](generated/networkx.algorithms.shortest_paths.generic.shortest_path_length.html) * [average\_shortest\_path\_length](generated/networkx.algorithms.shortest_paths.generic.average_shortest_path_length.html) * [has\_path](generated/networkx.algorithms.shortest_paths.generic.has_path.html) * [Advanced Interface](shortest_paths.html#module-networkx.algorithms.shortest_paths.unweighted) * [Dense Graphs](shortest_paths.html#module-networkx.algorithms.shortest_paths.dense) * [A\* Algorithm](shortest_paths.html#module-networkx.algorithms.shortest_paths.astar) * [Similarity Measures](similarity.html) * [graph\_edit\_distance](generated/networkx.algorithms.similarity.graph_edit_distance.html) * [optimal\_edit\_paths](generated/networkx.algorithms.similarity.optimal_edit_paths.html) * [optimize\_graph\_edit\_distance](generated/networkx.algorithms.similarity.optimize_graph_edit_distance.html) * [optimize\_edit\_paths](generated/networkx.algorithms.similarity.optimize_edit_paths.html) * [simrank\_similarity](generated/networkx.algorithms.similarity.simrank_similarity.html) * [panther\_similarity](generated/networkx.algorithms.similarity.panther_similarity.html) * [generate\_random\_paths](generated/networkx.algorithms.similarity.generate_random_paths.html) * [Simple Paths](simple_paths.html) * [all\_simple\_paths](generated/networkx.algorithms.simple_paths.all_simple_paths.html) * [all\_simple\_edge\_paths](generated/networkx.algorithms.simple_paths.all_simple_edge_paths.html) * [is\_simple\_path](generated/networkx.algorithms.simple_paths.is_simple_path.html) * [shortest\_simple\_paths](generated/networkx.algorithms.simple_paths.shortest_simple_paths.html) * [Small-world](smallworld.html) * [random\_reference](generated/networkx.algorithms.smallworld.random_reference.html) * [lattice\_reference](generated/networkx.algorithms.smallworld.lattice_reference.html) * [sigma](generated/networkx.algorithms.smallworld.sigma.html) * [omega](generated/networkx.algorithms.smallworld.omega.html) * [s metric](smetric.html) * [s\_metric](generated/networkx.algorithms.smetric.s_metric.html) * [Sparsifiers](sparsifiers.html) * [spanner](generated/networkx.algorithms.sparsifiers.spanner.html) * [Structural holes](structuralholes.html) * [constraint](generated/networkx.algorithms.structuralholes.constraint.html) * [effective\_size](generated/networkx.algorithms.structuralholes.effective_size.html) * [local\_constraint](generated/networkx.algorithms.structuralholes.local_constraint.html) * [Summarization](summarization.html) * [dedensify](generated/networkx.algorithms.summarization.dedensify.html) * [snap\_aggregation](generated/networkx.algorithms.summarization.snap_aggregation.html) * [Swap](swap.html) * [double\_edge\_swap](generated/networkx.algorithms.swap.double_edge_swap.html) * [directed\_edge\_swap](generated/networkx.algorithms.swap.directed_edge_swap.html) * [connected\_double\_edge\_swap](generated/networkx.algorithms.swap.connected_double_edge_swap.html) * [Threshold Graphs](threshold.html) * [find\_threshold\_graph](generated/networkx.algorithms.threshold.find_threshold_graph.html) * [is\_threshold\_graph](generated/networkx.algorithms.threshold.is_threshold_graph.html) * [Time dependent](time_dependent.html) * [cd\_index](generated/networkx.algorithms.time_dependent.cd_index.html) * [Tournament](tournament.html) * [hamiltonian\_path](generated/networkx.algorithms.tournament.hamiltonian_path.html) * [is\_reachable](generated/networkx.algorithms.tournament.is_reachable.html) * [is\_strongly\_connected](generated/networkx.algorithms.tournament.is_strongly_connected.html) * [is\_tournament](generated/networkx.algorithms.tournament.is_tournament.html) * [random\_tournament](generated/networkx.algorithms.tournament.random_tournament.html) * [score\_sequence](generated/networkx.algorithms.tournament.score_sequence.html) * [Traversal](traversal.html) * [Depth First Search](traversal.html#module-networkx.algorithms.traversal.depth_first_search) * [Breadth First Search](traversal.html#module-networkx.algorithms.traversal.breadth_first_search) * [Beam search](traversal.html#module-networkx.algorithms.traversal.beamsearch) * [Depth First Search on Edges](traversal.html#module-networkx.algorithms.traversal.edgedfs) * [Breadth First Search on Edges](traversal.html#module-networkx.algorithms.traversal.edgebfs) * [Tree](tree.html) * [Recognition](tree.html#module-networkx.algorithms.tree.recognition) * [Branchings and Spanning Arborescences](tree.html#module-networkx.algorithms.tree.branchings) * [Encoding and decoding](tree.html#module-networkx.algorithms.tree.coding) * [Operations](tree.html#module-networkx.algorithms.tree.operations) * [Spanning Trees](tree.html#module-networkx.algorithms.tree.mst) * [Decomposition](tree.html#module-networkx.algorithms.tree.decomposition) * [Exceptions](tree.html#exceptions) * [Triads](triads.html) * [triadic\_census](generated/networkx.algorithms.triads.triadic_census.html) * [random\_triad](generated/networkx.algorithms.triads.random_triad.html) * [triads\_by\_type](generated/networkx.algorithms.triads.triads_by_type.html) * [triad\_type](generated/networkx.algorithms.triads.triad_type.html) * [is\_triad](generated/networkx.algorithms.triads.is_triad.html) * [all\_triads](generated/networkx.algorithms.triads.all_triads.html) * [all\_triplets](generated/networkx.algorithms.triads.all_triplets.html) * [Vitality](vitality.html) * [closeness\_vitality](generated/networkx.algorithms.vitality.closeness_vitality.html) * [Voronoi cells](voronoi.html) * [voronoi\_cells](generated/networkx.algorithms.voronoi.voronoi_cells.html) * [Walks](walks.html) * [number\_of\_walks](generated/networkx.algorithms.walks.number_of_walks.html) * [Wiener Index](wiener.html) * [References](wiener.html#references) * [wiener\_index](generated/networkx.algorithms.wiener.wiener_index.html) * [schultz\_index](generated/networkx.algorithms.wiener.schultz_index.html) * [gutman\_index](generated/networkx.algorithms.wiener.gutman_index.html) --- # Graph types — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Graph types[#](#graph-types "Link to this heading") ==================================================== NetworkX provides data structures and methods for storing graphs. All NetworkX graph classes allow (hashable) Python objects as nodes and any Python object can be assigned as an edge attribute. The choice of graph class depends on the structure of the graph you want to represent. Which graph class should I use?[#](#which-graph-class-should-i-use "Link to this heading") ------------------------------------------------------------------------------------------- | Networkx Class | Type | Self-loops allowed | Parallel edges allowed | | --- | --- | --- | --- | | Graph | undirected | Yes | No | | DiGraph | directed | Yes | No | | MultiGraph | undirected | Yes | Yes | | MultiDiGraph | directed | Yes | Yes | Basic graph types[#](#basic-graph-types "Link to this heading") ---------------------------------------------------------------- * [Graph—Undirected graphs with self loops](graph.html) * [Overview](graph.html#overview) * [Methods](graph.html#methods) * [DiGraph—Directed graphs with self loops](digraph.html) * [Overview](digraph.html#overview) * [Methods](digraph.html#methods) * [MultiGraph—Undirected graphs with self loops and parallel edges](multigraph.html) * [Overview](multigraph.html#overview) * [Methods](multigraph.html#methods) * [MultiDiGraph—Directed graphs with self loops and parallel edges](multidigraph.html) * [Overview](multidigraph.html#overview) * [Methods](multidigraph.html#methods) Note NetworkX uses `dicts` to store the nodes and neighbors in a graph. So the reporting of nodes and edges for the base graph classes may not necessarily be consistent across versions and platforms; however, the reporting for CPython is consistent across platforms and versions after 3.6. Graph Views[#](#module-networkx.classes.graphviews "Link to this heading") --------------------------------------------------------------------------- View of Graphs as SubGraph, Reverse, Directed, Undirected. In some algorithms it is convenient to temporarily morph a graph to exclude some nodes or edges. It should be better to do that via a view than to remove and then re-add. In other algorithms it is convenient to temporarily morph a graph to reverse directed edges, or treat a directed graph as undirected, etc. This module provides those graph views. The resulting views are essentially read-only graphs that report data from the original graph object. We provide an attribute G.\_graph which points to the underlying graph object. Note: Since graphviews look like graphs, one can end up with view-of-view-of-view chains. Be careful with chains because they become very slow with about 15 nested views. For the common simple case of node induced subgraphs created from the graph class, we short-cut the chain by returning a subgraph of the original graph directly rather than a subgraph of a subgraph. We are careful not to disrupt any edge filter in the middle subgraph. In general, determining how to short-cut the chain is tricky and much harder with restricted\_views than with induced subgraphs. Often it is easiest to use .copy() to avoid chains. | | | | --- | --- | | [`generic_graph_view`](generated/networkx.classes.graphviews.generic_graph_view.html#networkx.classes.graphviews.generic_graph_view "networkx.classes.graphviews.generic_graph_view")
(G\[, create\_using\]) | Returns a read-only view of `G`. | | [`subgraph_view`](generated/networkx.classes.graphviews.subgraph_view.html#networkx.classes.graphviews.subgraph_view "networkx.classes.graphviews.subgraph_view")
(G, \*\[, filter\_node, filter\_edge\]) | View of `G` applying a filter on nodes and edges. | | [`reverse_view`](generated/networkx.classes.graphviews.reverse_view.html#networkx.classes.graphviews.reverse_view "networkx.classes.graphviews.reverse_view")
(G) | View of `G` with edge directions reversed | Core Views[#](#module-networkx.classes.coreviews "Link to this heading") ------------------------------------------------------------------------- Views of core data structures such as nested Mappings (e.g. dict-of-dicts). These `Views` often restrict element access, with either the entire view or layers of nested mappings being read-only. | | | | --- | --- | | [`AtlasView`](generated/networkx.classes.coreviews.AtlasView.html#networkx.classes.coreviews.AtlasView "networkx.classes.coreviews.AtlasView")
(d) | An AtlasView is a Read-only Mapping of Mappings. | | [`AdjacencyView`](generated/networkx.classes.coreviews.AdjacencyView.html#networkx.classes.coreviews.AdjacencyView "networkx.classes.coreviews.AdjacencyView")
(d) | An AdjacencyView is a Read-only Map of Maps of Maps. | | [`MultiAdjacencyView`](generated/networkx.classes.coreviews.MultiAdjacencyView.html#networkx.classes.coreviews.MultiAdjacencyView "networkx.classes.coreviews.MultiAdjacencyView")
(d) | An MultiAdjacencyView is a Read-only Map of Maps of Maps of Maps. | | [`UnionAtlas`](generated/networkx.classes.coreviews.UnionAtlas.html#networkx.classes.coreviews.UnionAtlas "networkx.classes.coreviews.UnionAtlas")
(succ, pred) | A read-only union of two atlases (dict-of-dict). | | [`UnionAdjacency`](generated/networkx.classes.coreviews.UnionAdjacency.html#networkx.classes.coreviews.UnionAdjacency "networkx.classes.coreviews.UnionAdjacency")
(succ, pred) | A read-only union of dict Adjacencies as a Map of Maps of Maps. | | [`UnionMultiInner`](generated/networkx.classes.coreviews.UnionMultiInner.html#networkx.classes.coreviews.UnionMultiInner "networkx.classes.coreviews.UnionMultiInner")
(succ, pred) | A read-only union of two inner dicts of MultiAdjacencies. | | [`UnionMultiAdjacency`](generated/networkx.classes.coreviews.UnionMultiAdjacency.html#networkx.classes.coreviews.UnionMultiAdjacency "networkx.classes.coreviews.UnionMultiAdjacency")
(succ, pred) | A read-only union of two dict MultiAdjacencies. | | [`FilterAtlas`](generated/networkx.classes.coreviews.FilterAtlas.html#networkx.classes.coreviews.FilterAtlas "networkx.classes.coreviews.FilterAtlas")
(d, NODE\_OK) | A read-only Mapping of Mappings with filtering criteria for nodes. | | [`FilterAdjacency`](generated/networkx.classes.coreviews.FilterAdjacency.html#networkx.classes.coreviews.FilterAdjacency "networkx.classes.coreviews.FilterAdjacency")
(d, NODE\_OK, EDGE\_OK) | A read-only Mapping of Mappings with filtering criteria for nodes and edges. | | [`FilterMultiInner`](generated/networkx.classes.coreviews.FilterMultiInner.html#networkx.classes.coreviews.FilterMultiInner "networkx.classes.coreviews.FilterMultiInner")
(d, NODE\_OK, EDGE\_OK) | A read-only Mapping of Mappings with filtering criteria for nodes and edges. | | [`FilterMultiAdjacency`](generated/networkx.classes.coreviews.FilterMultiAdjacency.html#networkx.classes.coreviews.FilterMultiAdjacency "networkx.classes.coreviews.FilterMultiAdjacency")
(d, NODE\_OK, EDGE\_OK) | A read-only Mapping of Mappings with filtering criteria for nodes and edges. | Filters[#](#filters "Link to this heading") -------------------------------------------- Note Filters can be used with views to restrict the view (or expand it). They can filter nodes or filter edges. These examples are intended to help you build new ones. They may instead contain all the filters you ever need. Filter factories to hide or show sets of nodes and edges. These filters return the function used when creating `SubGraph`. | | | | --- | --- | | [`no_filter`](generated/networkx.classes.filters.no_filter.html#networkx.classes.filters.no_filter "networkx.classes.filters.no_filter")
(\*items) | Returns a filter function that always evaluates to True. | | [`hide_nodes`](generated/networkx.classes.filters.hide_nodes.html#networkx.classes.filters.hide_nodes "networkx.classes.filters.hide_nodes")
(nodes) | Returns a filter function that hides specific nodes. | | [`hide_edges`](generated/networkx.classes.filters.hide_edges.html#networkx.classes.filters.hide_edges "networkx.classes.filters.hide_edges")
(edges) | Returns a filter function that hides specific undirected edges. | | [`hide_diedges`](generated/networkx.classes.filters.hide_diedges.html#networkx.classes.filters.hide_diedges "networkx.classes.filters.hide_diedges")
(edges) | Returns a filter function that hides specific directed edges. | | [`hide_multidiedges`](generated/networkx.classes.filters.hide_multidiedges.html#networkx.classes.filters.hide_multidiedges "networkx.classes.filters.hide_multidiedges")
(edges) | Returns a filter function that hides specific multi-directed edges. | | [`hide_multiedges`](generated/networkx.classes.filters.hide_multiedges.html#networkx.classes.filters.hide_multiedges "networkx.classes.filters.hide_multiedges")
(edges) | Returns a filter function that hides specific multi-undirected edges. | | [`show_nodes`](generated/networkx.classes.filters.show_nodes.html#networkx.classes.filters.show_nodes "networkx.classes.filters.show_nodes")
(nodes) | Filter class to show specific nodes. | | [`show_edges`](generated/networkx.classes.filters.show_edges.html#networkx.classes.filters.show_edges "networkx.classes.filters.show_edges")
(edges) | Returns a filter function that shows specific undirected edges. | | [`show_diedges`](generated/networkx.classes.filters.show_diedges.html#networkx.classes.filters.show_diedges "networkx.classes.filters.show_diedges")
(edges) | Returns a filter function that shows specific directed edges. | | [`show_multidiedges`](generated/networkx.classes.filters.show_multidiedges.html#networkx.classes.filters.show_multidiedges "networkx.classes.filters.show_multidiedges")
(edges) | Returns a filter function that shows specific multi-directed edges. | | [`show_multiedges`](generated/networkx.classes.filters.show_multiedges.html#networkx.classes.filters.show_multiedges "networkx.classes.filters.show_multiedges")
(edges) | Returns a filter function that shows specific multi-undirected edges. | On this page --- # Functions — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Functions[#](#module-networkx.classes.function "Link to this heading") ======================================================================= Functional interface to graph methods and assorted utilities. Graph[#](#graph "Link to this heading") ---------------------------------------- | | | | --- | --- | | [`degree`](generated/networkx.classes.function.degree.html#networkx.classes.function.degree "networkx.classes.function.degree")
(G\[, nbunch, weight\]) | Returns a degree view of single node or of nbunch of nodes. | | [`degree_histogram`](generated/networkx.classes.function.degree_histogram.html#networkx.classes.function.degree_histogram "networkx.classes.function.degree_histogram")
(G) | Returns a list of the frequency of each degree value. | | [`density`](generated/networkx.classes.function.density.html#networkx.classes.function.density "networkx.classes.function.density")
(G) | Returns the density of a graph. | | [`create_empty_copy`](generated/networkx.classes.function.create_empty_copy.html#networkx.classes.function.create_empty_copy "networkx.classes.function.create_empty_copy")
(G\[, with\_data\]) | Returns a copy of the graph G with all of the edges removed. | | [`is_directed`](generated/networkx.classes.function.is_directed.html#networkx.classes.function.is_directed "networkx.classes.function.is_directed")
(G) | Return True if graph is directed. | | [`to_directed`](generated/networkx.classes.function.to_directed.html#networkx.classes.function.to_directed "networkx.classes.function.to_directed")
(graph) | Returns a directed view of the graph `graph`. | | [`to_undirected`](generated/networkx.classes.function.to_undirected.html#networkx.classes.function.to_undirected "networkx.classes.function.to_undirected")
(graph) | Returns an undirected view of the graph `graph`. | | [`is_empty`](generated/networkx.classes.function.is_empty.html#networkx.classes.function.is_empty "networkx.classes.function.is_empty")
(G) | Returns True if `G` has no edges. | | [`add_star`](generated/networkx.classes.function.add_star.html#networkx.classes.function.add_star "networkx.classes.function.add_star")
(G\_to\_add\_to, nodes\_for\_star, \*\*attr) | Add a star to Graph G\_to\_add\_to. | | [`add_path`](generated/networkx.classes.function.add_path.html#networkx.classes.function.add_path "networkx.classes.function.add_path")
(G\_to\_add\_to, nodes\_for\_path, \*\*attr) | Add a path to the Graph G\_to\_add\_to. | | [`add_cycle`](generated/networkx.classes.function.add_cycle.html#networkx.classes.function.add_cycle "networkx.classes.function.add_cycle")
(G\_to\_add\_to, nodes\_for\_cycle, \*\*attr) | Add a cycle to the Graph G\_to\_add\_to. | | [`subgraph`](generated/networkx.classes.function.subgraph.html#networkx.classes.function.subgraph "networkx.classes.function.subgraph")
(G, nbunch) | Returns the subgraph induced on nodes in nbunch. | | [`induced_subgraph`](generated/networkx.classes.function.induced_subgraph.html#networkx.classes.function.induced_subgraph "networkx.classes.function.induced_subgraph")
(G, nbunch) | Returns a SubGraph view of `G` showing only nodes in nbunch. | | [`restricted_view`](generated/networkx.classes.function.restricted_view.html#networkx.classes.function.restricted_view "networkx.classes.function.restricted_view")
(G, nodes, edges) | Returns a view of `G` with hidden nodes and edges. | | [`edge_subgraph`](generated/networkx.classes.function.edge_subgraph.html#networkx.classes.function.edge_subgraph "networkx.classes.function.edge_subgraph")
(G, edges) | Returns a view of the subgraph induced by the specified edges. | Nodes[#](#nodes "Link to this heading") ---------------------------------------- | | | | --- | --- | | [`nodes`](generated/networkx.classes.function.nodes.html#networkx.classes.function.nodes "networkx.classes.function.nodes")
(G) | Returns a NodeView over the graph nodes. | | [`number_of_nodes`](generated/networkx.classes.function.number_of_nodes.html#networkx.classes.function.number_of_nodes "networkx.classes.function.number_of_nodes")
(G) | Returns the number of nodes in the graph. | | [`neighbors`](generated/networkx.classes.function.neighbors.html#networkx.classes.function.neighbors "networkx.classes.function.neighbors")
(G, n) | Returns an iterator over all neighbors of node n. | | [`all_neighbors`](generated/networkx.classes.function.all_neighbors.html#networkx.classes.function.all_neighbors "networkx.classes.function.all_neighbors")
(graph, node) | Returns all of the neighbors of a node in the graph. | | [`non_neighbors`](generated/networkx.classes.function.non_neighbors.html#networkx.classes.function.non_neighbors "networkx.classes.function.non_neighbors")
(graph, node) | Returns the non-neighbors of the node in the graph. | | [`common_neighbors`](generated/networkx.classes.function.common_neighbors.html#networkx.classes.function.common_neighbors "networkx.classes.function.common_neighbors")
(G, u, v) | Returns the common neighbors of two nodes in a graph. | Edges[#](#edges "Link to this heading") ---------------------------------------- | | | | --- | --- | | [`edges`](generated/networkx.classes.function.edges.html#networkx.classes.function.edges "networkx.classes.function.edges")
(G\[, nbunch\]) | Returns an edge view of edges incident to nodes in nbunch. | | [`number_of_edges`](generated/networkx.classes.function.number_of_edges.html#networkx.classes.function.number_of_edges "networkx.classes.function.number_of_edges")
(G) | Returns the number of edges in the graph. | | [`density`](generated/networkx.classes.function.density.html#networkx.classes.function.density "networkx.classes.function.density")
(G) | Returns the density of a graph. | | [`non_edges`](generated/networkx.classes.function.non_edges.html#networkx.classes.function.non_edges "networkx.classes.function.non_edges")
(graph) | Returns the nonexistent edges in the graph. | Self loops[#](#self-loops "Link to this heading") -------------------------------------------------- | | | | --- | --- | | [`selfloop_edges`](generated/networkx.classes.function.selfloop_edges.html#networkx.classes.function.selfloop_edges "networkx.classes.function.selfloop_edges")
(G\[, data, keys, default\]) | Returns an iterator over selfloop edges. | | [`number_of_selfloops`](generated/networkx.classes.function.number_of_selfloops.html#networkx.classes.function.number_of_selfloops "networkx.classes.function.number_of_selfloops")
(G) | Returns the number of selfloop edges. | | [`nodes_with_selfloops`](generated/networkx.classes.function.nodes_with_selfloops.html#networkx.classes.function.nodes_with_selfloops "networkx.classes.function.nodes_with_selfloops")
(G) | Returns an iterator over nodes with self loops. | Attributes[#](#attributes "Link to this heading") -------------------------------------------------- | | | | --- | --- | | [`is_weighted`](generated/networkx.classes.function.is_weighted.html#networkx.classes.function.is_weighted "networkx.classes.function.is_weighted")
(G\[, edge, weight\]) | Returns True if `G` has weighted edges. | | [`is_negatively_weighted`](generated/networkx.classes.function.is_negatively_weighted.html#networkx.classes.function.is_negatively_weighted "networkx.classes.function.is_negatively_weighted")
(G\[, edge, weight\]) | Returns True if `G` has negatively weighted edges. | | [`set_node_attributes`](generated/networkx.classes.function.set_node_attributes.html#networkx.classes.function.set_node_attributes "networkx.classes.function.set_node_attributes")
(G, values\[, name\]) | Sets node attributes from a given value or dictionary of values. | | [`get_node_attributes`](generated/networkx.classes.function.get_node_attributes.html#networkx.classes.function.get_node_attributes "networkx.classes.function.get_node_attributes")
(G, name\[, default\]) | Get node attributes from graph | | [`set_edge_attributes`](generated/networkx.classes.function.set_edge_attributes.html#networkx.classes.function.set_edge_attributes "networkx.classes.function.set_edge_attributes")
(G, values\[, name\]) | Sets edge attributes from a given value or dictionary of values. | | [`get_edge_attributes`](generated/networkx.classes.function.get_edge_attributes.html#networkx.classes.function.get_edge_attributes "networkx.classes.function.get_edge_attributes")
(G, name\[, default\]) | Get edge attributes from graph | Paths[#](#paths "Link to this heading") ---------------------------------------- | | | | --- | --- | | [`is_path`](generated/networkx.classes.function.is_path.html#networkx.classes.function.is_path "networkx.classes.function.is_path")
(G, path) | Returns whether or not the specified path exists. | | [`path_weight`](generated/networkx.classes.function.path_weight.html#networkx.classes.function.path_weight "networkx.classes.function.path_weight")
(G, path, weight) | Returns total cost associated with specified path and weight | Freezing graph structure[#](#freezing-graph-structure "Link to this heading") ------------------------------------------------------------------------------ | | | | --- | --- | | [`freeze`](generated/networkx.classes.function.freeze.html#networkx.classes.function.freeze "networkx.classes.function.freeze")
(G) | Modify graph to prevent further change by adding or removing nodes or edges. | | [`is_frozen`](generated/networkx.classes.function.is_frozen.html#networkx.classes.function.is_frozen "networkx.classes.function.is_frozen")
(G) | Returns True if graph is frozen. | On this page --- # Linear algebra — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Linear algebra[#](#linear-algebra "Link to this heading") ========================================================== Graph Matrix[#](#module-networkx.linalg.graphmatrix "Link to this heading") ---------------------------------------------------------------------------- Adjacency matrix and incidence matrix of graphs. | | | | --- | --- | | [`adjacency_matrix`](generated/networkx.linalg.graphmatrix.adjacency_matrix.html#networkx.linalg.graphmatrix.adjacency_matrix "networkx.linalg.graphmatrix.adjacency_matrix")
(G\[, nodelist, dtype, weight\]) | Returns adjacency matrix of `G`. | | [`incidence_matrix`](generated/networkx.linalg.graphmatrix.incidence_matrix.html#networkx.linalg.graphmatrix.incidence_matrix "networkx.linalg.graphmatrix.incidence_matrix")
(G\[, nodelist, edgelist, ...\]) | Returns incidence matrix of G. | Laplacian Matrix[#](#module-networkx.linalg.laplacianmatrix "Link to this heading") ------------------------------------------------------------------------------------ Laplacian matrix of graphs. All calculations here are done using the out-degree. For Laplacians using in-degree, use `G.reverse(copy=False)` instead of `G` and take the transpose. The [`laplacian_matrix`](generated/networkx.linalg.laplacianmatrix.laplacian_matrix.html#networkx.linalg.laplacianmatrix.laplacian_matrix "networkx.linalg.laplacianmatrix.laplacian_matrix") function provides an unnormalized matrix, while [`normalized_laplacian_matrix`](generated/networkx.linalg.laplacianmatrix.normalized_laplacian_matrix.html#networkx.linalg.laplacianmatrix.normalized_laplacian_matrix "networkx.linalg.laplacianmatrix.normalized_laplacian_matrix") , [`directed_laplacian_matrix`](generated/networkx.linalg.laplacianmatrix.directed_laplacian_matrix.html#networkx.linalg.laplacianmatrix.directed_laplacian_matrix "networkx.linalg.laplacianmatrix.directed_laplacian_matrix") , and [`directed_combinatorial_laplacian_matrix`](generated/networkx.linalg.laplacianmatrix.directed_combinatorial_laplacian_matrix.html#networkx.linalg.laplacianmatrix.directed_combinatorial_laplacian_matrix "networkx.linalg.laplacianmatrix.directed_combinatorial_laplacian_matrix") are all normalized. | | | | --- | --- | | [`laplacian_matrix`](generated/networkx.linalg.laplacianmatrix.laplacian_matrix.html#networkx.linalg.laplacianmatrix.laplacian_matrix "networkx.linalg.laplacianmatrix.laplacian_matrix")
(G\[, nodelist, weight\]) | Returns the Laplacian matrix of G. | | [`normalized_laplacian_matrix`](generated/networkx.linalg.laplacianmatrix.normalized_laplacian_matrix.html#networkx.linalg.laplacianmatrix.normalized_laplacian_matrix "networkx.linalg.laplacianmatrix.normalized_laplacian_matrix")
(G\[, nodelist, ...\]) | Returns the normalized Laplacian matrix of G. | | [`directed_laplacian_matrix`](generated/networkx.linalg.laplacianmatrix.directed_laplacian_matrix.html#networkx.linalg.laplacianmatrix.directed_laplacian_matrix "networkx.linalg.laplacianmatrix.directed_laplacian_matrix")
(G\[, nodelist, ...\]) | Returns the directed Laplacian matrix of G. | | [`directed_combinatorial_laplacian_matrix`](generated/networkx.linalg.laplacianmatrix.directed_combinatorial_laplacian_matrix.html#networkx.linalg.laplacianmatrix.directed_combinatorial_laplacian_matrix "networkx.linalg.laplacianmatrix.directed_combinatorial_laplacian_matrix")
(G\[, ...\]) | Return the directed combinatorial Laplacian matrix of G. | | [`total_spanning_tree_weight`](generated/networkx.linalg.laplacianmatrix.total_spanning_tree_weight.html#networkx.linalg.laplacianmatrix.total_spanning_tree_weight "networkx.linalg.laplacianmatrix.total_spanning_tree_weight")
(G\[, weight, root\]) | Returns the total weight of all spanning trees of `G`. | Bethe Hessian Matrix[#](#module-networkx.linalg.bethehessianmatrix "Link to this heading") ------------------------------------------------------------------------------------------- Bethe Hessian or deformed Laplacian matrix of graphs. | | | | --- | --- | | [`bethe_hessian_matrix`](generated/networkx.linalg.bethehessianmatrix.bethe_hessian_matrix.html#networkx.linalg.bethehessianmatrix.bethe_hessian_matrix "networkx.linalg.bethehessianmatrix.bethe_hessian_matrix")
(G\[, r, nodelist\]) | Returns the Bethe Hessian matrix of G. | Algebraic Connectivity[#](#module-networkx.linalg.algebraicconnectivity "Link to this heading") ------------------------------------------------------------------------------------------------ Algebraic connectivity and Fiedler vectors of undirected graphs. | | | | --- | --- | | [`algebraic_connectivity`](generated/networkx.linalg.algebraicconnectivity.algebraic_connectivity.html#networkx.linalg.algebraicconnectivity.algebraic_connectivity "networkx.linalg.algebraicconnectivity.algebraic_connectivity")
(G\[, weight, ...\]) | Returns the algebraic connectivity of an undirected graph. | | [`fiedler_vector`](generated/networkx.linalg.algebraicconnectivity.fiedler_vector.html#networkx.linalg.algebraicconnectivity.fiedler_vector "networkx.linalg.algebraicconnectivity.fiedler_vector")
(G\[, weight, normalized, tol, ...\]) | Returns the Fiedler vector of a connected undirected graph. | | [`spectral_ordering`](generated/networkx.linalg.algebraicconnectivity.spectral_ordering.html#networkx.linalg.algebraicconnectivity.spectral_ordering "networkx.linalg.algebraicconnectivity.spectral_ordering")
(G\[, weight, normalized, ...\]) | Compute the spectral\_ordering of a graph. | | [`spectral_bisection`](generated/networkx.linalg.algebraicconnectivity.spectral_bisection.html#networkx.linalg.algebraicconnectivity.spectral_bisection "networkx.linalg.algebraicconnectivity.spectral_bisection")
(G\[, weight, normalized, ...\]) | Bisect the graph using the Fiedler vector. | Attribute Matrices[#](#module-networkx.linalg.attrmatrix "Link to this heading") --------------------------------------------------------------------------------- Functions for constructing matrix-like objects from graph attributes. | | | | --- | --- | | [`attr_matrix`](generated/networkx.linalg.attrmatrix.attr_matrix.html#networkx.linalg.attrmatrix.attr_matrix "networkx.linalg.attrmatrix.attr_matrix")
(G\[, edge\_attr, node\_attr, ...\]) | Returns the attribute matrix using attributes from `G` as a numpy array. | | [`attr_sparse_matrix`](generated/networkx.linalg.attrmatrix.attr_sparse_matrix.html#networkx.linalg.attrmatrix.attr_sparse_matrix "networkx.linalg.attrmatrix.attr_sparse_matrix")
(G\[, edge\_attr, ...\]) | Returns a SciPy sparse array using attributes from G. | Modularity Matrices[#](#module-networkx.linalg.modularitymatrix "Link to this heading") ---------------------------------------------------------------------------------------- Modularity matrix of graphs. | | | | --- | --- | | [`modularity_matrix`](generated/networkx.linalg.modularitymatrix.modularity_matrix.html#networkx.linalg.modularitymatrix.modularity_matrix "networkx.linalg.modularitymatrix.modularity_matrix")
(G\[, nodelist, weight\]) | Returns the modularity matrix of G. | | [`directed_modularity_matrix`](generated/networkx.linalg.modularitymatrix.directed_modularity_matrix.html#networkx.linalg.modularitymatrix.directed_modularity_matrix "networkx.linalg.modularitymatrix.directed_modularity_matrix")
(G\[, nodelist, weight\]) | Returns the directed modularity matrix of G. | Spectrum[#](#module-networkx.linalg.spectrum "Link to this heading") --------------------------------------------------------------------- Eigenvalue spectrum of graphs. | | | | --- | --- | | [`adjacency_spectrum`](generated/networkx.linalg.spectrum.adjacency_spectrum.html#networkx.linalg.spectrum.adjacency_spectrum "networkx.linalg.spectrum.adjacency_spectrum")
(G\[, weight\]) | Returns eigenvalues of the adjacency matrix of G. | | [`laplacian_spectrum`](generated/networkx.linalg.spectrum.laplacian_spectrum.html#networkx.linalg.spectrum.laplacian_spectrum "networkx.linalg.spectrum.laplacian_spectrum")
(G\[, weight\]) | Returns eigenvalues of the Laplacian of G | | [`bethe_hessian_spectrum`](generated/networkx.linalg.spectrum.bethe_hessian_spectrum.html#networkx.linalg.spectrum.bethe_hessian_spectrum "networkx.linalg.spectrum.bethe_hessian_spectrum")
(G\[, r\]) | Returns eigenvalues of the Bethe Hessian matrix of G. | | [`normalized_laplacian_spectrum`](generated/networkx.linalg.spectrum.normalized_laplacian_spectrum.html#networkx.linalg.spectrum.normalized_laplacian_spectrum "networkx.linalg.spectrum.normalized_laplacian_spectrum")
(G\[, weight\]) | Return eigenvalues of the normalized Laplacian of G | | [`modularity_spectrum`](generated/networkx.linalg.spectrum.modularity_spectrum.html#networkx.linalg.spectrum.modularity_spectrum "networkx.linalg.spectrum.modularity_spectrum")
(G) | Returns eigenvalues of the modularity matrix of G. | On this page --- # Geospatial Examples Description — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Geospatial Examples Description[#](#geospatial-examples-description "Link to this heading") ============================================================================================ Functions for reading and writing shapefiles are provided in NetworkX versions <3.0. However, we recommend that you use the following libraries when working with geospatial data (including reading and writing shapefiles). Geospatial Python Libraries[#](#geospatial-python-libraries "Link to this heading") ------------------------------------------------------------------------------------ [GeoPandas](https://geopandas.readthedocs.io/) provides interoperability between geospatial formats and storage mechanisms (e.g., databases) and Pandas data frames for tabular-oriented processing of spatial data, as well as a wide array of supporting functionality including spatial indices, spatial predicates (e.g., test if geometries intersect each other), spatial operations (e.g., the area of overlap between intersecting polygons), and more. See the following examples that use GeoPandas: ![Delaunay graphs from geographic points](../../_images/sphx_glr_plot_delaunay_thumb.png) [Delaunay graphs from geographic points](plot_delaunay.html#sphx-glr-auto-examples-geospatial-plot-delaunay-py) [#](#id1 "Link to this image") ![Graphs from a set of lines](../../_images/sphx_glr_plot_lines_thumb.png) [Graphs from a set of lines](plot_lines.html#sphx-glr-auto-examples-geospatial-plot-lines-py) [#](#id2 "Link to this image") ![Graphs from Polygons](../../_images/sphx_glr_plot_polygons_thumb.png) [Graphs from Polygons](plot_polygons.html#sphx-glr-auto-examples-geospatial-plot-polygons-py) [#](#id3 "Link to this image") ![Graphs from geographic points](../../_images/sphx_glr_plot_points_thumb.png) [Graphs from geographic points](plot_points.html#sphx-glr-auto-examples-geospatial-plot-points-py) [#](#id4 "Link to this image") ![OpenStreetMap with OSMnx](../../_images/sphx_glr_plot_osmnx_thumb.png) [OpenStreetMap with OSMnx](plot_osmnx.html#sphx-glr-auto-examples-geospatial-plot-osmnx-py) [#](#id5 "Link to this image") [PySAL](https://pysal.org/) provides a rich suite of spatial analysis algorithms. From a network analysis context, [spatial weights](https://pysal.org/libpysal/api.html#spatial-weights) provide… (Levi please add more here). See the following examples that use PySAL: ![Delaunay graphs from geographic points](../../_images/sphx_glr_plot_delaunay_thumb.png) [Delaunay graphs from geographic points](plot_delaunay.html#sphx-glr-auto-examples-geospatial-plot-delaunay-py) [#](#id6 "Link to this image") ![Graphs from a set of lines](../../_images/sphx_glr_plot_lines_thumb.png) [Graphs from a set of lines](plot_lines.html#sphx-glr-auto-examples-geospatial-plot-lines-py) [#](#id7 "Link to this image") ![Graphs from Polygons](../../_images/sphx_glr_plot_polygons_thumb.png) [Graphs from Polygons](plot_polygons.html#sphx-glr-auto-examples-geospatial-plot-polygons-py) [#](#id8 "Link to this image") ![Graphs from geographic points](../../_images/sphx_glr_plot_points_thumb.png) [Graphs from geographic points](plot_points.html#sphx-glr-auto-examples-geospatial-plot-points-py) [#](#id9 "Link to this image") [momepy](http://docs.momepy.org/en/stable/) builds on top of GeoPandas and PySAL to provide a suite of algorithms focused on urban morphology. From a network analysis context, momepy enables you to convert your line geometry to [`networkx.MultiGraph`](../../reference/classes/multigraph.html#networkx.MultiGraph "networkx.MultiGraph") and back to [`geopandas.GeoDataFrame`](https://geopandas.org/en/stable/docs/reference/api/geopandas.GeoDataFrame.html#geopandas.GeoDataFrame "(in GeoPandas v1.0.1)") and apply a range of analytical functions aiming at morphological description of (street) network configurations. See the following examples that use momepy: ![Graphs from a set of lines](../../_images/sphx_glr_plot_lines_thumb.png) [Graphs from a set of lines](plot_lines.html#sphx-glr-auto-examples-geospatial-plot-lines-py) [#](#id10 "Link to this image") [OSMnx](https://osmnx.readthedocs.io/) provides a set of tools to retrieve, model, project, analyze, and visualize OpenStreetMap street networks (and any other networked infrastructure) as [`networkx.MultiDiGraph`](../../reference/classes/multidigraph.html#networkx.MultiDiGraph "networkx.MultiDiGraph") objects, and convert these MultiDiGraphs to/from [`geopandas.GeoDataFrame`](https://geopandas.org/en/stable/docs/reference/api/geopandas.GeoDataFrame.html#geopandas.GeoDataFrame "(in GeoPandas v1.0.1)") . It can automatically add node/edge attributes for: elevation and grade (using the Google Maps Elevation API), edge travel speed, edge traversal time, and edge bearing. It can also retrieve any other spatial data from OSM (such as building footprints, public parks, schools, transit stops, etc) as Geopandas GeoDataFrames. See the following examples that use OSMnx: ![OpenStreetMap with OSMnx](../../_images/sphx_glr_plot_osmnx_thumb.png) [OpenStreetMap with OSMnx](plot_osmnx.html#sphx-glr-auto-examples-geospatial-plot-osmnx-py) [#](#id11 "Link to this image") Key Concepts[#](#key-concepts "Link to this heading") ------------------------------------------------------ One of the essential tasks in network analysis of geospatial data is defining the spatial relationships between spatial features (points, lines, or polygons). `PySAL` provides several ways of representing these spatial relationships between features using the concept of spatial weights. These include relationships such as `Queen`, `Rook`, … (Levi please add more here with a brief explanation of each). `momepy` allows representation of street networks as both primal and dual graphs (in a street network analysis sense). The primal approach turns intersections into Graph nodes and street segments into edges, a format which is used for a majority of morphological studies. The dual approach uses street segments as nodes and intersection topology as edges, which allows encoding of angular information (i.e an analysis can be weighted by angles between street segments instead of their length). `OSMnx` represents street networks as primal, nonplanar, directed graphs with possible self-loops and parallel edges to model real-world street network form and flow. Nodes represent intersections and dead-ends, and edges represent the street segments linking them. Details of OSMnx’s modeling methodology are available at [https://doi.org/10.1016/j.compenvurbsys.2017.05.004](https://doi.org/10.1016/j.compenvurbsys.2017.05.004) Learn More[#](#learn-more "Link to this heading") -------------------------------------------------- To learn more see [Geographic Data Science with PySAL and the PyData Stack](https://geographicdata.science/book/intro.html) . On this page --- # Graph generators — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Graph generators[#](#graph-generators "Link to this heading") ============================================================== Atlas[#](#module-networkx.generators.atlas "Link to this heading") ------------------------------------------------------------------- Generators for the small graph atlas. | | | | --- | --- | | [`graph_atlas`](generated/networkx.generators.atlas.graph_atlas.html#networkx.generators.atlas.graph_atlas "networkx.generators.atlas.graph_atlas")
(i) | Returns graph number `i` from the Graph Atlas. | | [`graph_atlas_g`](generated/networkx.generators.atlas.graph_atlas_g.html#networkx.generators.atlas.graph_atlas_g "networkx.generators.atlas.graph_atlas_g")
() | Returns the list of all graphs with up to seven nodes named in the Graph Atlas. | Classic[#](#module-networkx.generators.classic "Link to this heading") ----------------------------------------------------------------------- Generators for some classic graphs. The typical graph builder function is called as follows: \>>> G \= nx.complete\_graph(100) returning the complete graph on n nodes labeled 0, .., 99 as a simple graph. Except for [`empty_graph`](generated/networkx.generators.classic.empty_graph.html#networkx.generators.classic.empty_graph "networkx.generators.classic.empty_graph") , all the functions in this module return a Graph class (i.e. a simple, undirected graph). | | | | --- | --- | | [`balanced_tree`](generated/networkx.generators.classic.balanced_tree.html#networkx.generators.classic.balanced_tree "networkx.generators.classic.balanced_tree")
(r, h\[, create\_using\]) | Returns the perfectly balanced `r`\-ary tree of height `h`. | | [`barbell_graph`](generated/networkx.generators.classic.barbell_graph.html#networkx.generators.classic.barbell_graph "networkx.generators.classic.barbell_graph")
(m1, m2\[, create\_using\]) | Returns the Barbell Graph: two complete graphs connected by a path. | | [`binomial_tree`](generated/networkx.generators.classic.binomial_tree.html#networkx.generators.classic.binomial_tree "networkx.generators.classic.binomial_tree")
(n\[, create\_using\]) | Returns the Binomial Tree of order n. | | [`complete_graph`](generated/networkx.generators.classic.complete_graph.html#networkx.generators.classic.complete_graph "networkx.generators.classic.complete_graph")
(n\[, create\_using\]) | Return the complete graph `K_n` with n nodes. | | [`complete_multipartite_graph`](generated/networkx.generators.classic.complete_multipartite_graph.html#networkx.generators.classic.complete_multipartite_graph "networkx.generators.classic.complete_multipartite_graph")
(\*subset\_sizes) | Returns the complete multipartite graph with the specified subset sizes. | | [`circular_ladder_graph`](generated/networkx.generators.classic.circular_ladder_graph.html#networkx.generators.classic.circular_ladder_graph "networkx.generators.classic.circular_ladder_graph")
(n\[, create\_using\]) | Returns the circular ladder graph \\(CL\_n\\) of length n. | | [`circulant_graph`](generated/networkx.generators.classic.circulant_graph.html#networkx.generators.classic.circulant_graph "networkx.generators.classic.circulant_graph")
(n, offsets\[, create\_using\]) | Returns the circulant graph \\(Ci\_n(x\_1, x\_2, ..., x\_m)\\) with \\(n\\) nodes. | | [`cycle_graph`](generated/networkx.generators.classic.cycle_graph.html#networkx.generators.classic.cycle_graph "networkx.generators.classic.cycle_graph")
(n\[, create\_using\]) | Returns the cycle graph \\(C\_n\\) of cyclically connected nodes. | | [`dorogovtsev_goltsev_mendes_graph`](generated/networkx.generators.classic.dorogovtsev_goltsev_mendes_graph.html#networkx.generators.classic.dorogovtsev_goltsev_mendes_graph "networkx.generators.classic.dorogovtsev_goltsev_mendes_graph")
(n\[, ...\]) | Returns the hierarchically constructed Dorogovtsev--Goltsev--Mendes graph. | | [`empty_graph`](generated/networkx.generators.classic.empty_graph.html#networkx.generators.classic.empty_graph "networkx.generators.classic.empty_graph")
(\[n, create\_using, default\]) | Returns the empty graph with n nodes and zero edges. | | [`full_rary_tree`](generated/networkx.generators.classic.full_rary_tree.html#networkx.generators.classic.full_rary_tree "networkx.generators.classic.full_rary_tree")
(r, n\[, create\_using\]) | Creates a full r-ary tree of `n` nodes. | | [`kneser_graph`](generated/networkx.generators.classic.kneser_graph.html#networkx.generators.classic.kneser_graph "networkx.generators.classic.kneser_graph")
(n, k) | Returns the Kneser Graph with parameters `n` and `k`. | | [`ladder_graph`](generated/networkx.generators.classic.ladder_graph.html#networkx.generators.classic.ladder_graph "networkx.generators.classic.ladder_graph")
(n\[, create\_using\]) | Returns the Ladder graph of length n. | | [`lollipop_graph`](generated/networkx.generators.classic.lollipop_graph.html#networkx.generators.classic.lollipop_graph "networkx.generators.classic.lollipop_graph")
(m, n\[, create\_using\]) | Returns the Lollipop Graph; `K_m` connected to `P_n`. | | [`null_graph`](generated/networkx.generators.classic.null_graph.html#networkx.generators.classic.null_graph "networkx.generators.classic.null_graph")
(\[create\_using\]) | Returns the Null graph with no nodes or edges. | | [`path_graph`](generated/networkx.generators.classic.path_graph.html#networkx.generators.classic.path_graph "networkx.generators.classic.path_graph")
(n\[, create\_using\]) | Returns the Path graph `P_n` of linearly connected nodes. | | [`star_graph`](generated/networkx.generators.classic.star_graph.html#networkx.generators.classic.star_graph "networkx.generators.classic.star_graph")
(n\[, create\_using\]) | Return the star graph | | [`tadpole_graph`](generated/networkx.generators.classic.tadpole_graph.html#networkx.generators.classic.tadpole_graph "networkx.generators.classic.tadpole_graph")
(m, n\[, create\_using\]) | Returns the (m,n)-tadpole graph; `C_m` connected to `P_n`. | | [`trivial_graph`](generated/networkx.generators.classic.trivial_graph.html#networkx.generators.classic.trivial_graph "networkx.generators.classic.trivial_graph")
(\[create\_using\]) | Return the Trivial graph with one node (with label 0) and no edges. | | [`turan_graph`](generated/networkx.generators.classic.turan_graph.html#networkx.generators.classic.turan_graph "networkx.generators.classic.turan_graph")
(n, r) | Return the Turan Graph | | [`wheel_graph`](generated/networkx.generators.classic.wheel_graph.html#networkx.generators.classic.wheel_graph "networkx.generators.classic.wheel_graph")
(n\[, create\_using\]) | Return the wheel graph | Expanders[#](#module-networkx.generators.expanders "Link to this heading") --------------------------------------------------------------------------- Provides explicit constructions of expander graphs. | | | | --- | --- | | [`margulis_gabber_galil_graph`](generated/networkx.generators.expanders.margulis_gabber_galil_graph.html#networkx.generators.expanders.margulis_gabber_galil_graph "networkx.generators.expanders.margulis_gabber_galil_graph")
(n\[, create\_using\]) | Returns the Margulis-Gabber-Galil undirected MultiGraph on `n^2` nodes. | | [`chordal_cycle_graph`](generated/networkx.generators.expanders.chordal_cycle_graph.html#networkx.generators.expanders.chordal_cycle_graph "networkx.generators.expanders.chordal_cycle_graph")
(p\[, create\_using\]) | Returns the chordal cycle graph on `p` nodes. | | [`paley_graph`](generated/networkx.generators.expanders.paley_graph.html#networkx.generators.expanders.paley_graph "networkx.generators.expanders.paley_graph")
(p\[, create\_using\]) | Returns the Paley \\(\\frac{(p-1)}{2}\\) -regular graph on \\(p\\) nodes. | | [`maybe_regular_expander`](generated/networkx.generators.expanders.maybe_regular_expander.html#networkx.generators.expanders.maybe_regular_expander "networkx.generators.expanders.maybe_regular_expander")
(n, d, \*\[, ...\]) | Utility for creating a random regular expander. | | [`is_regular_expander`](generated/networkx.generators.expanders.is_regular_expander.html#networkx.generators.expanders.is_regular_expander "networkx.generators.expanders.is_regular_expander")
(G, \*\[, epsilon\]) | Determines whether the graph G is a regular expander. | | [`random_regular_expander_graph`](generated/networkx.generators.expanders.random_regular_expander_graph.html#networkx.generators.expanders.random_regular_expander_graph "networkx.generators.expanders.random_regular_expander_graph")
(n, d, \*\[, ...\]) | Returns a random regular expander graph on \\(n\\) nodes with degree \\(d\\). | Lattice[#](#module-networkx.generators.lattice "Link to this heading") ----------------------------------------------------------------------- Functions for generating grid graphs and lattices The [`grid_2d_graph()`](generated/networkx.generators.lattice.grid_2d_graph.html#networkx.generators.lattice.grid_2d_graph "networkx.generators.lattice.grid_2d_graph") , [`triangular_lattice_graph()`](generated/networkx.generators.lattice.triangular_lattice_graph.html#networkx.generators.lattice.triangular_lattice_graph "networkx.generators.lattice.triangular_lattice_graph") , and [`hexagonal_lattice_graph()`](generated/networkx.generators.lattice.hexagonal_lattice_graph.html#networkx.generators.lattice.hexagonal_lattice_graph "networkx.generators.lattice.hexagonal_lattice_graph") functions correspond to the three [regular tilings of the plane](https://en.wikipedia.org/wiki/List_of_regular_polytopes_and_compounds#Euclidean_tilings) , the square, triangular, and hexagonal tilings, respectively. [`grid_graph()`](generated/networkx.generators.lattice.grid_graph.html#networkx.generators.lattice.grid_graph "networkx.generators.lattice.grid_graph") and [`hypercube_graph()`](generated/networkx.generators.lattice.hypercube_graph.html#networkx.generators.lattice.hypercube_graph "networkx.generators.lattice.hypercube_graph") are similar for arbitrary dimensions. Useful relevant discussion can be found about [Triangular Tiling](https://en.wikipedia.org/wiki/Triangular_tiling) , and [Square, Hex and Triangle Grids](http://www-cs-students.stanford.edu/~amitp/game-programming/grids/) | | | | --- | --- | | [`grid_2d_graph`](generated/networkx.generators.lattice.grid_2d_graph.html#networkx.generators.lattice.grid_2d_graph "networkx.generators.lattice.grid_2d_graph")
(m, n\[, periodic, create\_using\]) | Returns the two-dimensional grid graph. | | [`grid_graph`](generated/networkx.generators.lattice.grid_graph.html#networkx.generators.lattice.grid_graph "networkx.generators.lattice.grid_graph")
(dim\[, periodic\]) | Returns the _n_\-dimensional grid graph. | | [`hexagonal_lattice_graph`](generated/networkx.generators.lattice.hexagonal_lattice_graph.html#networkx.generators.lattice.hexagonal_lattice_graph "networkx.generators.lattice.hexagonal_lattice_graph")
(m, n\[, periodic, ...\]) | Returns an `m` by `n` hexagonal lattice graph. | | [`hypercube_graph`](generated/networkx.generators.lattice.hypercube_graph.html#networkx.generators.lattice.hypercube_graph "networkx.generators.lattice.hypercube_graph")
(n) | Returns the _n_\-dimensional hypercube graph. | | [`triangular_lattice_graph`](generated/networkx.generators.lattice.triangular_lattice_graph.html#networkx.generators.lattice.triangular_lattice_graph "networkx.generators.lattice.triangular_lattice_graph")
(m, n\[, periodic, ...\]) | Returns the \\(m\\) by \\(n\\) triangular lattice graph. | Small[#](#module-networkx.generators.small "Link to this heading") ------------------------------------------------------------------- Various small and named graphs, together with some compact generators. | | | | --- | --- | | [`LCF_graph`](generated/networkx.generators.small.LCF_graph.html#networkx.generators.small.LCF_graph "networkx.generators.small.LCF_graph")
(n, shift\_list, repeats\[, create\_using\]) | Return the cubic graph specified in LCF notation. | | [`bull_graph`](generated/networkx.generators.small.bull_graph.html#networkx.generators.small.bull_graph "networkx.generators.small.bull_graph")
(\[create\_using\]) | Returns the Bull Graph | | [`chvatal_graph`](generated/networkx.generators.small.chvatal_graph.html#networkx.generators.small.chvatal_graph "networkx.generators.small.chvatal_graph")
(\[create\_using\]) | Returns the Chvátal Graph | | [`cubical_graph`](generated/networkx.generators.small.cubical_graph.html#networkx.generators.small.cubical_graph "networkx.generators.small.cubical_graph")
(\[create\_using\]) | Returns the 3-regular Platonic Cubical Graph | | [`desargues_graph`](generated/networkx.generators.small.desargues_graph.html#networkx.generators.small.desargues_graph "networkx.generators.small.desargues_graph")
(\[create\_using\]) | Returns the Desargues Graph | | [`diamond_graph`](generated/networkx.generators.small.diamond_graph.html#networkx.generators.small.diamond_graph "networkx.generators.small.diamond_graph")
(\[create\_using\]) | Returns the Diamond graph | | [`dodecahedral_graph`](generated/networkx.generators.small.dodecahedral_graph.html#networkx.generators.small.dodecahedral_graph "networkx.generators.small.dodecahedral_graph")
(\[create\_using\]) | Returns the Platonic Dodecahedral graph. | | [`frucht_graph`](generated/networkx.generators.small.frucht_graph.html#networkx.generators.small.frucht_graph "networkx.generators.small.frucht_graph")
(\[create\_using\]) | Returns the Frucht Graph. | | [`heawood_graph`](generated/networkx.generators.small.heawood_graph.html#networkx.generators.small.heawood_graph "networkx.generators.small.heawood_graph")
(\[create\_using\]) | Returns the Heawood Graph, a (3,6) cage. | | [`hoffman_singleton_graph`](generated/networkx.generators.small.hoffman_singleton_graph.html#networkx.generators.small.hoffman_singleton_graph "networkx.generators.small.hoffman_singleton_graph")
() | Returns the Hoffman-Singleton Graph. | | [`house_graph`](generated/networkx.generators.small.house_graph.html#networkx.generators.small.house_graph "networkx.generators.small.house_graph")
(\[create\_using\]) | Returns the House graph (square with triangle on top) | | [`house_x_graph`](generated/networkx.generators.small.house_x_graph.html#networkx.generators.small.house_x_graph "networkx.generators.small.house_x_graph")
(\[create\_using\]) | Returns the House graph with a cross inside the house square. | | [`icosahedral_graph`](generated/networkx.generators.small.icosahedral_graph.html#networkx.generators.small.icosahedral_graph "networkx.generators.small.icosahedral_graph")
(\[create\_using\]) | Returns the Platonic Icosahedral graph. | | [`krackhardt_kite_graph`](generated/networkx.generators.small.krackhardt_kite_graph.html#networkx.generators.small.krackhardt_kite_graph "networkx.generators.small.krackhardt_kite_graph")
(\[create\_using\]) | Returns the Krackhardt Kite Social Network. | | [`moebius_kantor_graph`](generated/networkx.generators.small.moebius_kantor_graph.html#networkx.generators.small.moebius_kantor_graph "networkx.generators.small.moebius_kantor_graph")
(\[create\_using\]) | Returns the Moebius-Kantor graph. | | [`octahedral_graph`](generated/networkx.generators.small.octahedral_graph.html#networkx.generators.small.octahedral_graph "networkx.generators.small.octahedral_graph")
(\[create\_using\]) | Returns the Platonic Octahedral graph. | | [`pappus_graph`](generated/networkx.generators.small.pappus_graph.html#networkx.generators.small.pappus_graph "networkx.generators.small.pappus_graph")
() | Returns the Pappus graph. | | [`petersen_graph`](generated/networkx.generators.small.petersen_graph.html#networkx.generators.small.petersen_graph "networkx.generators.small.petersen_graph")
(\[create\_using\]) | Returns the Petersen graph. | | [`sedgewick_maze_graph`](generated/networkx.generators.small.sedgewick_maze_graph.html#networkx.generators.small.sedgewick_maze_graph "networkx.generators.small.sedgewick_maze_graph")
(\[create\_using\]) | Return a small maze with a cycle. | | [`tetrahedral_graph`](generated/networkx.generators.small.tetrahedral_graph.html#networkx.generators.small.tetrahedral_graph "networkx.generators.small.tetrahedral_graph")
(\[create\_using\]) | Returns the 3-regular Platonic Tetrahedral graph. | | [`truncated_cube_graph`](generated/networkx.generators.small.truncated_cube_graph.html#networkx.generators.small.truncated_cube_graph "networkx.generators.small.truncated_cube_graph")
(\[create\_using\]) | Returns the skeleton of the truncated cube. | | [`truncated_tetrahedron_graph`](generated/networkx.generators.small.truncated_tetrahedron_graph.html#networkx.generators.small.truncated_tetrahedron_graph "networkx.generators.small.truncated_tetrahedron_graph")
(\[create\_using\]) | Returns the skeleton of the truncated Platonic tetrahedron. | | [`tutte_graph`](generated/networkx.generators.small.tutte_graph.html#networkx.generators.small.tutte_graph "networkx.generators.small.tutte_graph")
(\[create\_using\]) | Returns the Tutte graph. | Random Graphs[#](#module-networkx.generators.random_graphs "Link to this heading") ----------------------------------------------------------------------------------- Generators for random graphs. | | | | --- | --- | | [`fast_gnp_random_graph`](generated/networkx.generators.random_graphs.fast_gnp_random_graph.html#networkx.generators.random_graphs.fast_gnp_random_graph "networkx.generators.random_graphs.fast_gnp_random_graph")
(n, p\[, seed, ...\]) | Returns a \\(G\_{n,p}\\) random graph, also known as an Erdős-Rényi graph or a binomial graph. | | [`gnp_random_graph`](generated/networkx.generators.random_graphs.gnp_random_graph.html#networkx.generators.random_graphs.gnp_random_graph "networkx.generators.random_graphs.gnp_random_graph")
(n, p\[, seed, directed, ...\]) | Returns a \\(G\_{n,p}\\) random graph, also known as an Erdős-Rényi graph or a binomial graph. | | [`dense_gnm_random_graph`](generated/networkx.generators.random_graphs.dense_gnm_random_graph.html#networkx.generators.random_graphs.dense_gnm_random_graph "networkx.generators.random_graphs.dense_gnm_random_graph")
(n, m\[, seed, ...\]) | Returns a \\(G\_{n,m}\\) random graph. | | [`gnm_random_graph`](generated/networkx.generators.random_graphs.gnm_random_graph.html#networkx.generators.random_graphs.gnm_random_graph "networkx.generators.random_graphs.gnm_random_graph")
(n, m\[, seed, directed, ...\]) | Returns a \\(G\_{n,m}\\) random graph. | | [`erdos_renyi_graph`](generated/networkx.generators.random_graphs.erdos_renyi_graph.html#networkx.generators.random_graphs.erdos_renyi_graph "networkx.generators.random_graphs.erdos_renyi_graph")
(n, p\[, seed, directed, ...\]) | Returns a \\(G\_{n,p}\\) random graph, also known as an Erdős-Rényi graph or a binomial graph. | | [`binomial_graph`](generated/networkx.generators.random_graphs.binomial_graph.html#networkx.generators.random_graphs.binomial_graph "networkx.generators.random_graphs.binomial_graph")
(n, p\[, seed, directed, ...\]) | Returns a \\(G\_{n,p}\\) random graph, also known as an Erdős-Rényi graph or a binomial graph. | | [`newman_watts_strogatz_graph`](generated/networkx.generators.random_graphs.newman_watts_strogatz_graph.html#networkx.generators.random_graphs.newman_watts_strogatz_graph "networkx.generators.random_graphs.newman_watts_strogatz_graph")
(n, k, p\[, seed, ...\]) | Returns a Newman–Watts–Strogatz small-world graph. | | [`watts_strogatz_graph`](generated/networkx.generators.random_graphs.watts_strogatz_graph.html#networkx.generators.random_graphs.watts_strogatz_graph "networkx.generators.random_graphs.watts_strogatz_graph")
(n, k, p\[, seed, ...\]) | Returns a Watts–Strogatz small-world graph. | | [`connected_watts_strogatz_graph`](generated/networkx.generators.random_graphs.connected_watts_strogatz_graph.html#networkx.generators.random_graphs.connected_watts_strogatz_graph "networkx.generators.random_graphs.connected_watts_strogatz_graph")
(n, k, p\[, ...\]) | Returns a connected Watts–Strogatz small-world graph. | | [`random_regular_graph`](generated/networkx.generators.random_graphs.random_regular_graph.html#networkx.generators.random_graphs.random_regular_graph "networkx.generators.random_graphs.random_regular_graph")
(d, n\[, seed, create\_using\]) | Returns a random \\(d\\)\-regular graph on \\(n\\) nodes. | | [`barabasi_albert_graph`](generated/networkx.generators.random_graphs.barabasi_albert_graph.html#networkx.generators.random_graphs.barabasi_albert_graph "networkx.generators.random_graphs.barabasi_albert_graph")
(n, m\[, seed, ...\]) | Returns a random graph using Barabási–Albert preferential attachment | | [`dual_barabasi_albert_graph`](generated/networkx.generators.random_graphs.dual_barabasi_albert_graph.html#networkx.generators.random_graphs.dual_barabasi_albert_graph "networkx.generators.random_graphs.dual_barabasi_albert_graph")
(n, m1, m2, p\[, ...\]) | Returns a random graph using dual Barabási–Albert preferential attachment | | [`extended_barabasi_albert_graph`](generated/networkx.generators.random_graphs.extended_barabasi_albert_graph.html#networkx.generators.random_graphs.extended_barabasi_albert_graph "networkx.generators.random_graphs.extended_barabasi_albert_graph")
(n, m, p, q\[, ...\]) | Returns an extended Barabási–Albert model graph. | | [`powerlaw_cluster_graph`](generated/networkx.generators.random_graphs.powerlaw_cluster_graph.html#networkx.generators.random_graphs.powerlaw_cluster_graph "networkx.generators.random_graphs.powerlaw_cluster_graph")
(n, m, p\[, seed, ...\]) | Holme and Kim algorithm for growing graphs with powerlaw degree distribution and approximate average clustering. | | [`random_kernel_graph`](generated/networkx.generators.random_graphs.random_kernel_graph.html#networkx.generators.random_graphs.random_kernel_graph "networkx.generators.random_graphs.random_kernel_graph")
(n, kernel\_integral\[, ...\]) | Returns an random graph based on the specified kernel. | | [`random_lobster`](generated/networkx.generators.random_graphs.random_lobster.html#networkx.generators.random_graphs.random_lobster "networkx.generators.random_graphs.random_lobster")
(n, p1, p2\[, seed, create\_using\]) | Returns a random lobster graph. | | [`random_shell_graph`](generated/networkx.generators.random_graphs.random_shell_graph.html#networkx.generators.random_graphs.random_shell_graph "networkx.generators.random_graphs.random_shell_graph")
(constructor\[, seed, ...\]) | Returns a random shell graph for the constructor given. | | [`random_powerlaw_tree`](generated/networkx.generators.random_graphs.random_powerlaw_tree.html#networkx.generators.random_graphs.random_powerlaw_tree "networkx.generators.random_graphs.random_powerlaw_tree")
(n\[, gamma, seed, ...\]) | Returns a tree with a power law degree distribution. | | [`random_powerlaw_tree_sequence`](generated/networkx.generators.random_graphs.random_powerlaw_tree_sequence.html#networkx.generators.random_graphs.random_powerlaw_tree_sequence "networkx.generators.random_graphs.random_powerlaw_tree_sequence")
(n\[, gamma, ...\]) | Returns a degree sequence for a tree with a power law distribution. | | [`random_kernel_graph`](generated/networkx.generators.random_graphs.random_kernel_graph.html#networkx.generators.random_graphs.random_kernel_graph "networkx.generators.random_graphs.random_kernel_graph")
(n, kernel\_integral\[, ...\]) | Returns an random graph based on the specified kernel. | Duplication Divergence[#](#module-networkx.generators.duplication "Link to this heading") ------------------------------------------------------------------------------------------ Functions for generating graphs based on the “duplication” method. These graph generators start with a small initial graph then duplicate nodes and (partially) duplicate their edges. These functions are generally inspired by biological networks. | | | | --- | --- | | [`duplication_divergence_graph`](generated/networkx.generators.duplication.duplication_divergence_graph.html#networkx.generators.duplication.duplication_divergence_graph "networkx.generators.duplication.duplication_divergence_graph")
(n, p\[, seed, ...\]) | Returns an undirected graph using the duplication-divergence model. | | [`partial_duplication_graph`](generated/networkx.generators.duplication.partial_duplication_graph.html#networkx.generators.duplication.partial_duplication_graph "networkx.generators.duplication.partial_duplication_graph")
(N, n, p, q\[, ...\]) | Returns a random graph using the partial duplication model. | Degree Sequence[#](#module-networkx.generators.degree_seq "Link to this heading") ---------------------------------------------------------------------------------- Generate graphs with a given degree sequence or expected degree sequence. | | | | --- | --- | | [`configuration_model`](generated/networkx.generators.degree_seq.configuration_model.html#networkx.generators.degree_seq.configuration_model "networkx.generators.degree_seq.configuration_model")
(deg\_sequence\[, ...\]) | Returns a random graph with the given degree sequence. | | [`directed_configuration_model`](generated/networkx.generators.degree_seq.directed_configuration_model.html#networkx.generators.degree_seq.directed_configuration_model "networkx.generators.degree_seq.directed_configuration_model")
(...\[, ...\]) | Returns a directed\_random graph with the given degree sequences. | | [`expected_degree_graph`](generated/networkx.generators.degree_seq.expected_degree_graph.html#networkx.generators.degree_seq.expected_degree_graph "networkx.generators.degree_seq.expected_degree_graph")
(w\[, seed, selfloops\]) | Returns a random graph with given expected degrees. | | [`havel_hakimi_graph`](generated/networkx.generators.degree_seq.havel_hakimi_graph.html#networkx.generators.degree_seq.havel_hakimi_graph "networkx.generators.degree_seq.havel_hakimi_graph")
(deg\_sequence\[, create\_using\]) | Returns a simple graph with given degree sequence constructed using the Havel-Hakimi algorithm. | | [`directed_havel_hakimi_graph`](generated/networkx.generators.degree_seq.directed_havel_hakimi_graph.html#networkx.generators.degree_seq.directed_havel_hakimi_graph "networkx.generators.degree_seq.directed_havel_hakimi_graph")
(in\_deg\_sequence, ...) | Returns a directed graph with the given degree sequences. | | [`degree_sequence_tree`](generated/networkx.generators.degree_seq.degree_sequence_tree.html#networkx.generators.degree_seq.degree_sequence_tree "networkx.generators.degree_seq.degree_sequence_tree")
(deg\_sequence\[, ...\]) | Make a tree for the given degree sequence. | | [`random_degree_sequence_graph`](generated/networkx.generators.degree_seq.random_degree_sequence_graph.html#networkx.generators.degree_seq.random_degree_sequence_graph "networkx.generators.degree_seq.random_degree_sequence_graph")
(sequence\[, ...\]) | Returns a simple random graph with the given degree sequence. | Random Clustered[#](#module-networkx.generators.random_clustered "Link to this heading") ----------------------------------------------------------------------------------------- Generate graphs with given degree and triangle sequence. | | | | --- | --- | | [`random_clustered_graph`](generated/networkx.generators.random_clustered.random_clustered_graph.html#networkx.generators.random_clustered.random_clustered_graph "networkx.generators.random_clustered.random_clustered_graph")
(joint\_degree\_sequence) | Generate a random graph with the given joint independent edge degree and triangle degree sequence. | Directed[#](#module-networkx.generators.directed "Link to this heading") ------------------------------------------------------------------------- Generators for some directed graphs, including growing network (GN) graphs and scale-free graphs. | | | | --- | --- | | [`gn_graph`](generated/networkx.generators.directed.gn_graph.html#networkx.generators.directed.gn_graph "networkx.generators.directed.gn_graph")
(n\[, kernel, create\_using, seed\]) | Returns the growing network (GN) digraph with `n` nodes. | | [`gnr_graph`](generated/networkx.generators.directed.gnr_graph.html#networkx.generators.directed.gnr_graph "networkx.generators.directed.gnr_graph")
(n, p\[, create\_using, seed\]) | Returns the growing network with redirection (GNR) digraph with `n` nodes and redirection probability `p`. | | [`gnc_graph`](generated/networkx.generators.directed.gnc_graph.html#networkx.generators.directed.gnc_graph "networkx.generators.directed.gnc_graph")
(n\[, create\_using, seed\]) | Returns the growing network with copying (GNC) digraph with `n` nodes. | | [`random_k_out_graph`](generated/networkx.generators.directed.random_k_out_graph.html#networkx.generators.directed.random_k_out_graph "networkx.generators.directed.random_k_out_graph")
(n, k, alpha\[, ...\]) | Returns a random `k`\-out graph with preferential attachment. | | [`scale_free_graph`](generated/networkx.generators.directed.scale_free_graph.html#networkx.generators.directed.scale_free_graph "networkx.generators.directed.scale_free_graph")
(n\[, alpha, beta, gamma, ...\]) | Returns a scale-free directed graph. | Geometric[#](#module-networkx.generators.geometric "Link to this heading") --------------------------------------------------------------------------- Generators for geometric graphs. | | | | --- | --- | | [`geometric_edges`](generated/networkx.generators.geometric.geometric_edges.html#networkx.generators.geometric.geometric_edges "networkx.generators.geometric.geometric_edges")
(G, radius\[, p, pos\_name\]) | Returns edge list of node pairs within `radius` of each other. | | [`geographical_threshold_graph`](generated/networkx.generators.geometric.geographical_threshold_graph.html#networkx.generators.geometric.geographical_threshold_graph "networkx.generators.geometric.geographical_threshold_graph")
(n, theta\[, ...\]) | Returns a geographical threshold graph. | | [`navigable_small_world_graph`](generated/networkx.generators.geometric.navigable_small_world_graph.html#networkx.generators.geometric.navigable_small_world_graph "networkx.generators.geometric.navigable_small_world_graph")
(n\[, p, q, r, ...\]) | Returns a navigable small-world graph. | | [`random_geometric_graph`](generated/networkx.generators.geometric.random_geometric_graph.html#networkx.generators.geometric.random_geometric_graph "networkx.generators.geometric.random_geometric_graph")
(n, radius\[, dim, ...\]) | Returns a random geometric graph in the unit cube of dimensions `dim`. | | [`soft_random_geometric_graph`](generated/networkx.generators.geometric.soft_random_geometric_graph.html#networkx.generators.geometric.soft_random_geometric_graph "networkx.generators.geometric.soft_random_geometric_graph")
(n, radius\[, ...\]) | Returns a soft random geometric graph in the unit cube. | | [`thresholded_random_geometric_graph`](generated/networkx.generators.geometric.thresholded_random_geometric_graph.html#networkx.generators.geometric.thresholded_random_geometric_graph "networkx.generators.geometric.thresholded_random_geometric_graph")
(n, ...\[, ...\]) | Returns a thresholded random geometric graph in the unit cube. | | [`waxman_graph`](generated/networkx.generators.geometric.waxman_graph.html#networkx.generators.geometric.waxman_graph "networkx.generators.geometric.waxman_graph")
(n\[, beta, alpha, L, domain, ...\]) | Returns a Waxman random graph. | | [`geometric_soft_configuration_graph`](generated/networkx.generators.geometric.geometric_soft_configuration_graph.html#networkx.generators.geometric.geometric_soft_configuration_graph "networkx.generators.geometric.geometric_soft_configuration_graph")
(\*, beta) | Returns a random graph from the geometric soft configuration model. | Line Graph[#](#module-networkx.generators.line "Link to this heading") ----------------------------------------------------------------------- Functions for generating line graphs. | | | | --- | --- | | [`line_graph`](generated/networkx.generators.line.line_graph.html#networkx.generators.line.line_graph "networkx.generators.line.line_graph")
(G\[, create\_using\]) | Returns the line graph of the graph or digraph `G`. | | [`inverse_line_graph`](generated/networkx.generators.line.inverse_line_graph.html#networkx.generators.line.inverse_line_graph "networkx.generators.line.inverse_line_graph")
(G) | Returns the inverse line graph of graph G. | Ego Graph[#](#module-networkx.generators.ego "Link to this heading") --------------------------------------------------------------------- Ego graph. | | | | --- | --- | | [`ego_graph`](generated/networkx.generators.ego.ego_graph.html#networkx.generators.ego.ego_graph "networkx.generators.ego.ego_graph")
(G, n\[, radius, center, ...\]) | Returns induced subgraph of neighbors centered at node n within a given radius. | Stochastic[#](#module-networkx.generators.stochastic "Link to this heading") ----------------------------------------------------------------------------- Functions for generating stochastic graphs from a given weighted directed graph. | | | | --- | --- | | [`stochastic_graph`](generated/networkx.generators.stochastic.stochastic_graph.html#networkx.generators.stochastic.stochastic_graph "networkx.generators.stochastic.stochastic_graph")
(G\[, copy, weight\]) | Returns a right-stochastic representation of directed graph `G`. | AS graph[#](#module-networkx.generators.internet_as_graphs "Link to this heading") ----------------------------------------------------------------------------------- Generates graphs resembling the Internet Autonomous System network | | | | --- | --- | | [`random_internet_as_graph`](generated/networkx.generators.internet_as_graphs.random_internet_as_graph.html#networkx.generators.internet_as_graphs.random_internet_as_graph "networkx.generators.internet_as_graphs.random_internet_as_graph")
(n\[, seed\]) | Generates a random undirected graph resembling the Internet AS network | Intersection[#](#module-networkx.generators.intersection "Link to this heading") --------------------------------------------------------------------------------- Generators for random intersection graphs. | | | | --- | --- | | [`uniform_random_intersection_graph`](generated/networkx.generators.intersection.uniform_random_intersection_graph.html#networkx.generators.intersection.uniform_random_intersection_graph "networkx.generators.intersection.uniform_random_intersection_graph")
(n, m, p\[, ...\]) | Returns a uniform random intersection graph. | | [`k_random_intersection_graph`](generated/networkx.generators.intersection.k_random_intersection_graph.html#networkx.generators.intersection.k_random_intersection_graph "networkx.generators.intersection.k_random_intersection_graph")
(n, m, k\[, seed\]) | Returns a intersection graph with randomly chosen attribute sets for each node that are of equal size (k). | | [`general_random_intersection_graph`](generated/networkx.generators.intersection.general_random_intersection_graph.html#networkx.generators.intersection.general_random_intersection_graph "networkx.generators.intersection.general_random_intersection_graph")
(n, m, p\[, ...\]) | Returns a random intersection graph with independent probabilities for connections between node and attribute sets. | Social Networks[#](#module-networkx.generators.social "Link to this heading") ------------------------------------------------------------------------------ Famous social networks. | | | | --- | --- | | [`karate_club_graph`](generated/networkx.generators.social.karate_club_graph.html#networkx.generators.social.karate_club_graph "networkx.generators.social.karate_club_graph")
() | Returns Zachary's Karate Club graph. | | [`davis_southern_women_graph`](generated/networkx.generators.social.davis_southern_women_graph.html#networkx.generators.social.davis_southern_women_graph "networkx.generators.social.davis_southern_women_graph")
() | Returns Davis Southern women social network. | | [`florentine_families_graph`](generated/networkx.generators.social.florentine_families_graph.html#networkx.generators.social.florentine_families_graph "networkx.generators.social.florentine_families_graph")
() | Returns Florentine families graph. | | [`les_miserables_graph`](generated/networkx.generators.social.les_miserables_graph.html#networkx.generators.social.les_miserables_graph "networkx.generators.social.les_miserables_graph")
() | Returns coappearance network of characters in the novel Les Miserables. | Community[#](#module-networkx.generators.community "Link to this heading") --------------------------------------------------------------------------- Generators for classes of graphs used in studying social networks. | | | | --- | --- | | [`caveman_graph`](generated/networkx.generators.community.caveman_graph.html#networkx.generators.community.caveman_graph "networkx.generators.community.caveman_graph")
(l, k) | Returns a caveman graph of `l` cliques of size `k`. | | [`connected_caveman_graph`](generated/networkx.generators.community.connected_caveman_graph.html#networkx.generators.community.connected_caveman_graph "networkx.generators.community.connected_caveman_graph")
(l, k) | Returns a connected caveman graph of `l` cliques of size `k`. | | [`gaussian_random_partition_graph`](generated/networkx.generators.community.gaussian_random_partition_graph.html#networkx.generators.community.gaussian_random_partition_graph "networkx.generators.community.gaussian_random_partition_graph")
(n, s, v, ...) | Generate a Gaussian random partition graph. | | [`LFR_benchmark_graph`](generated/networkx.generators.community.LFR_benchmark_graph.html#networkx.generators.community.LFR_benchmark_graph "networkx.generators.community.LFR_benchmark_graph")
(n, tau1, tau2, mu\[, ...\]) | Returns the LFR benchmark graph. | | [`planted_partition_graph`](generated/networkx.generators.community.planted_partition_graph.html#networkx.generators.community.planted_partition_graph "networkx.generators.community.planted_partition_graph")
(l, k, p\_in, p\_out\[, ...\]) | Returns the planted l-partition graph. | | [`random_partition_graph`](generated/networkx.generators.community.random_partition_graph.html#networkx.generators.community.random_partition_graph "networkx.generators.community.random_partition_graph")
(sizes, p\_in, p\_out\[, ...\]) | Returns the random partition graph with a partition of sizes. | | [`relaxed_caveman_graph`](generated/networkx.generators.community.relaxed_caveman_graph.html#networkx.generators.community.relaxed_caveman_graph "networkx.generators.community.relaxed_caveman_graph")
(l, k, p\[, seed\]) | Returns a relaxed caveman graph. | | [`ring_of_cliques`](generated/networkx.generators.community.ring_of_cliques.html#networkx.generators.community.ring_of_cliques "networkx.generators.community.ring_of_cliques")
(num\_cliques, clique\_size) | Defines a "ring of cliques" graph. | | [`stochastic_block_model`](generated/networkx.generators.community.stochastic_block_model.html#networkx.generators.community.stochastic_block_model "networkx.generators.community.stochastic_block_model")
(sizes, p\[, nodelist, ...\]) | Returns a stochastic block model graph. | | [`windmill_graph`](generated/networkx.generators.community.windmill_graph.html#networkx.generators.community.windmill_graph "networkx.generators.community.windmill_graph")
(n, k) | Generate a windmill graph. | Spectral[#](#module-networkx.generators.spectral_graph_forge "Link to this heading") ------------------------------------------------------------------------------------- Generates graphs with a given eigenvector structure | | | | --- | --- | | [`spectral_graph_forge`](generated/networkx.generators.spectral_graph_forge.spectral_graph_forge.html#networkx.generators.spectral_graph_forge.spectral_graph_forge "networkx.generators.spectral_graph_forge.spectral_graph_forge")
(G, alpha\[, ...\]) | Returns a random simple graph with spectrum resembling that of `G` | Trees[#](#module-networkx.generators.trees "Link to this heading") ------------------------------------------------------------------- Functions for generating trees. The functions sampling trees at random in this module come in two variants: labeled and unlabeled. The labeled variants sample from every possible tree with the given number of nodes uniformly at random. The unlabeled variants sample from every possible _isomorphism class_ of trees with the given number of nodes uniformly at random. To understand the difference, consider the following example. There are two isomorphism classes of trees with four nodes. One is that of the path graph, the other is that of the star graph. The unlabeled variant will return a line graph or a star graph with probability 1/2. The labeled variant will return the line graph with probability 3/4 and the star graph with probability 1/4, because there are more labeled variants of the line graph than of the star graph. More precisely, the line graph has an automorphism group of order 2, whereas the star graph has an automorphism group of order 6, so the line graph has three times as many labeled variants as the star graph, and thus three more chances to be drawn. Additionally, some functions in this module can sample rooted trees and forests uniformly at random. A rooted tree is a tree with a designated root node. A rooted forest is a disjoint union of rooted trees. | | | | --- | --- | | [`prefix_tree`](generated/networkx.generators.trees.prefix_tree.html#networkx.generators.trees.prefix_tree "networkx.generators.trees.prefix_tree")
(paths) | Creates a directed prefix tree from a list of paths. | | [`random_labeled_tree`](generated/networkx.generators.trees.random_labeled_tree.html#networkx.generators.trees.random_labeled_tree "networkx.generators.trees.random_labeled_tree")
(n, \*\[, seed\]) | Returns a labeled tree on `n` nodes chosen uniformly at random. | | [`random_labeled_rooted_tree`](generated/networkx.generators.trees.random_labeled_rooted_tree.html#networkx.generators.trees.random_labeled_rooted_tree "networkx.generators.trees.random_labeled_rooted_tree")
(n, \*\[, seed\]) | Returns a labeled rooted tree with `n` nodes. | | [`random_labeled_rooted_forest`](generated/networkx.generators.trees.random_labeled_rooted_forest.html#networkx.generators.trees.random_labeled_rooted_forest "networkx.generators.trees.random_labeled_rooted_forest")
(n, \*\[, seed\]) | Returns a labeled rooted forest with `n` nodes. | | [`random_unlabeled_tree`](generated/networkx.generators.trees.random_unlabeled_tree.html#networkx.generators.trees.random_unlabeled_tree "networkx.generators.trees.random_unlabeled_tree")
(n, \*\[, ...\]) | Returns a tree or list of trees chosen randomly. | | [`random_unlabeled_rooted_tree`](generated/networkx.generators.trees.random_unlabeled_rooted_tree.html#networkx.generators.trees.random_unlabeled_rooted_tree "networkx.generators.trees.random_unlabeled_rooted_tree")
(n, \*\[, ...\]) | Returns a number of unlabeled rooted trees uniformly at random | | [`random_unlabeled_rooted_forest`](generated/networkx.generators.trees.random_unlabeled_rooted_forest.html#networkx.generators.trees.random_unlabeled_rooted_forest "networkx.generators.trees.random_unlabeled_rooted_forest")
(n, \*\[, q, ...\]) | Returns a forest or list of forests selected at random. | Non Isomorphic Trees[#](#module-networkx.generators.nonisomorphic_trees "Link to this heading") ------------------------------------------------------------------------------------------------ Implementation of the Wright, Richmond, Odlyzko and McKay (WROM) algorithm for the enumeration of all non-isomorphic free trees of a given order. Rooted trees are represented by level sequences, i.e., lists in which the i-th element specifies the distance of vertex i to the root. | | | | --- | --- | | [`nonisomorphic_trees`](generated/networkx.generators.nonisomorphic_trees.nonisomorphic_trees.html#networkx.generators.nonisomorphic_trees.nonisomorphic_trees "networkx.generators.nonisomorphic_trees.nonisomorphic_trees")
(order\[, create\]) | Generates lists of nonisomorphic trees | | [`number_of_nonisomorphic_trees`](generated/networkx.generators.nonisomorphic_trees.number_of_nonisomorphic_trees.html#networkx.generators.nonisomorphic_trees.number_of_nonisomorphic_trees "networkx.generators.nonisomorphic_trees.number_of_nonisomorphic_trees")
(order) | Returns the number of nonisomorphic trees | Triads[#](#module-networkx.generators.triads "Link to this heading") --------------------------------------------------------------------- Functions that generate the triad graphs, that is, the possible digraphs on three nodes. | | | | --- | --- | | [`triad_graph`](generated/networkx.generators.triads.triad_graph.html#networkx.generators.triads.triad_graph "networkx.generators.triads.triad_graph")
(triad\_name) | Returns the triad graph with the given name. | Joint Degree Sequence[#](#module-networkx.generators.joint_degree_seq "Link to this heading") ---------------------------------------------------------------------------------------------- Generate graphs with a given joint degree and directed joint degree | | | | --- | --- | | [`is_valid_joint_degree`](generated/networkx.generators.joint_degree_seq.is_valid_joint_degree.html#networkx.generators.joint_degree_seq.is_valid_joint_degree "networkx.generators.joint_degree_seq.is_valid_joint_degree")
(joint\_degrees) | Checks whether the given joint degree dictionary is realizable. | | [`joint_degree_graph`](generated/networkx.generators.joint_degree_seq.joint_degree_graph.html#networkx.generators.joint_degree_seq.joint_degree_graph "networkx.generators.joint_degree_seq.joint_degree_graph")
(joint\_degrees\[, seed\]) | Generates a random simple graph with the given joint degree dictionary. | | [`is_valid_directed_joint_degree`](generated/networkx.generators.joint_degree_seq.is_valid_directed_joint_degree.html#networkx.generators.joint_degree_seq.is_valid_directed_joint_degree "networkx.generators.joint_degree_seq.is_valid_directed_joint_degree")
(in\_degrees, ...) | Checks whether the given directed joint degree input is realizable | | [`directed_joint_degree_graph`](generated/networkx.generators.joint_degree_seq.directed_joint_degree_graph.html#networkx.generators.joint_degree_seq.directed_joint_degree_graph "networkx.generators.joint_degree_seq.directed_joint_degree_graph")
(in\_degrees, ...) | Generates a random simple directed graph with the joint degree. | Mycielski[#](#module-networkx.generators.mycielski "Link to this heading") --------------------------------------------------------------------------- Functions related to the Mycielski Operation and the Mycielskian family of graphs. | | | | --- | --- | | [`mycielskian`](generated/networkx.generators.mycielski.mycielskian.html#networkx.generators.mycielski.mycielskian "networkx.generators.mycielski.mycielskian")
(G\[, iterations\]) | Returns the Mycielskian of a simple, undirected graph G | | [`mycielski_graph`](generated/networkx.generators.mycielski.mycielski_graph.html#networkx.generators.mycielski.mycielski_graph "networkx.generators.mycielski.mycielski_graph")
(n) | Generator for the n\_th Mycielski Graph. | Harary Graph[#](#module-networkx.generators.harary_graph "Link to this heading") --------------------------------------------------------------------------------- Generators for Harary graphs This module gives two generators for the Harary graph, which was introduced by the famous mathematician Frank Harary in his 1962 work [\[H\]](#re9eb9bbc2cf6-h) . The first generator gives the Harary graph that maximizes the node connectivity with given number of nodes and given number of edges. The second generator gives the Harary graph that minimizes the number of edges in the graph with given node connectivity and number of nodes. ### References[#](#references "Link to this heading") \[[H](#id1)\ \] Harary, F. “The Maximum Connectivity of a Graph.” Proc. Nat. Acad. Sci. USA 48, 1142-1146, 1962. | | | | --- | --- | | [`hnm_harary_graph`](generated/networkx.generators.harary_graph.hnm_harary_graph.html#networkx.generators.harary_graph.hnm_harary_graph "networkx.generators.harary_graph.hnm_harary_graph")
(n, m\[, create\_using\]) | Returns the Harary graph with given numbers of nodes and edges. | | [`hkn_harary_graph`](generated/networkx.generators.harary_graph.hkn_harary_graph.html#networkx.generators.harary_graph.hkn_harary_graph "networkx.generators.harary_graph.hkn_harary_graph")
(k, n\[, create\_using\]) | Returns the Harary graph with given node connectivity and node number. | Cographs[#](#module-networkx.generators.cographs "Link to this heading") ------------------------------------------------------------------------- Generators for cographs A cograph is a graph containing no path on four vertices. Cographs or \\(P\_4\\)\-free graphs can be obtained from a single vertex by disjoint union and complementation operations. ### References[#](#id2 "Link to this heading") \[0\] D.G. Corneil, H. Lerchs, L.Stewart Burlingham, “Complement reducible graphs”, Discrete Applied Mathematics, Volume 3, Issue 3, 1981, Pages 163-174, ISSN 0166-218X. | | | | --- | --- | | [`random_cograph`](generated/networkx.generators.cographs.random_cograph.html#networkx.generators.cographs.random_cograph "networkx.generators.cographs.random_cograph")
(n\[, seed\]) | Returns a random cograph with \\(2 ^ n\\) nodes. | Interval Graph[#](#module-networkx.generators.interval_graph "Link to this heading") ------------------------------------------------------------------------------------- Generators for interval graph. | | | | --- | --- | | [`interval_graph`](generated/networkx.generators.interval_graph.interval_graph.html#networkx.generators.interval_graph.interval_graph "networkx.generators.interval_graph.interval_graph")
(intervals) | Generates an interval graph for a list of intervals given. | Sudoku[#](#module-networkx.generators.sudoku "Link to this heading") --------------------------------------------------------------------- Generator for Sudoku graphs This module gives a generator for n-Sudoku graphs. It can be used to develop algorithms for solving or generating Sudoku puzzles. A completed Sudoku grid is a 9x9 array of integers between 1 and 9, with no number appearing twice in the same row, column, or 3x3 box. | | | | | --- | --- | --- | | 8 6 4

3 2 5

9 7 1 | 3 7 1

8 4 9

2 6 5 | 2 5 9

7 6 1

8 4 3 | | 4 3 6

1 9 8

2 5 7 | 1 9 2

6 5 7

4 8 3 | 5 8 7

4 3 2

9 1 6 | | 6 8 9

7 1 3

5 4 2 | 7 3 4

5 2 8

9 1 6 | 1 2 5

6 9 4

3 7 8 | The Sudoku graph is an undirected graph with 81 vertices, corresponding to the cells of a Sudoku grid. It is a regular graph of degree 20. Two distinct vertices are adjacent if and only if the corresponding cells belong to the same row, column, or box. A completed Sudoku grid corresponds to a vertex coloring of the Sudoku graph with nine colors. More generally, the n-Sudoku graph is a graph with n^4 vertices, corresponding to the cells of an n^2 by n^2 grid. Two distinct vertices are adjacent if and only if they belong to the same row, column, or n by n box. ### References[#](#id3 "Link to this heading") \[1\] Herzberg, A. M., & Murty, M. R. (2007). Sudoku squares and chromatic polynomials. Notices of the AMS, 54(6), 708-717. \[2\] Sander, Torsten (2009), “Sudoku graphs are integral”, Electronic Journal of Combinatorics, 16 (1): Note 25, 7pp, MR 2529816 \[3\] Wikipedia contributors. “Glossary of Sudoku.” Wikipedia, The Free Encyclopedia, 3 Dec. 2019. Web. 22 Dec. 2019. | | | | --- | --- | | [`sudoku_graph`](generated/networkx.generators.sudoku.sudoku_graph.html#networkx.generators.sudoku.sudoku_graph "networkx.generators.sudoku.sudoku_graph")
(\[n\]) | Returns the n-Sudoku graph. | Time Series[#](#module-networkx.generators.time_series "Link to this heading") ------------------------------------------------------------------------------- Time Series Graphs | | | | --- | --- | | [`visibility_graph`](generated/networkx.generators.time_series.visibility_graph.html#networkx.generators.time_series.visibility_graph "networkx.generators.time_series.visibility_graph")
(series) | Return a Visibility Graph of an input Time Series. | On this page --- # Reading and writing graphs — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Reading and writing graphs[#](#reading-and-writing-graphs "Link to this heading") ================================================================================== * [Adjacency List](adjlist.html) * [Format](adjlist.html#format) * [read\_adjlist](generated/networkx.readwrite.adjlist.read_adjlist.html) * [write\_adjlist](generated/networkx.readwrite.adjlist.write_adjlist.html) * [parse\_adjlist](generated/networkx.readwrite.adjlist.parse_adjlist.html) * [generate\_adjlist](generated/networkx.readwrite.adjlist.generate_adjlist.html) * [Multiline Adjacency List](multiline_adjlist.html) * [Format](multiline_adjlist.html#format) * [read\_multiline\_adjlist](generated/networkx.readwrite.multiline_adjlist.read_multiline_adjlist.html) * [write\_multiline\_adjlist](generated/networkx.readwrite.multiline_adjlist.write_multiline_adjlist.html) * [parse\_multiline\_adjlist](generated/networkx.readwrite.multiline_adjlist.parse_multiline_adjlist.html) * [generate\_multiline\_adjlist](generated/networkx.readwrite.multiline_adjlist.generate_multiline_adjlist.html) * [DOT](dot.html) * [pygraphviz](dot.html#pygraphviz) * [Edge List](edgelist.html) * [Format](edgelist.html#format) * [read\_edgelist](generated/networkx.readwrite.edgelist.read_edgelist.html) * [write\_edgelist](generated/networkx.readwrite.edgelist.write_edgelist.html) * [read\_weighted\_edgelist](generated/networkx.readwrite.edgelist.read_weighted_edgelist.html) * [write\_weighted\_edgelist](generated/networkx.readwrite.edgelist.write_weighted_edgelist.html) * [generate\_edgelist](generated/networkx.readwrite.edgelist.generate_edgelist.html) * [parse\_edgelist](generated/networkx.readwrite.edgelist.parse_edgelist.html) * [GEXF](gexf.html) * [Format](gexf.html#format) * [read\_gexf](generated/networkx.readwrite.gexf.read_gexf.html) * [write\_gexf](generated/networkx.readwrite.gexf.write_gexf.html) * [generate\_gexf](generated/networkx.readwrite.gexf.generate_gexf.html) * [relabel\_gexf\_graph](generated/networkx.readwrite.gexf.relabel_gexf_graph.html) * [GML](gml.html) * [read\_gml](generated/networkx.readwrite.gml.read_gml.html) * [write\_gml](generated/networkx.readwrite.gml.write_gml.html) * [parse\_gml](generated/networkx.readwrite.gml.parse_gml.html) * [generate\_gml](generated/networkx.readwrite.gml.generate_gml.html) * [literal\_destringizer](generated/networkx.readwrite.gml.literal_destringizer.html) * [literal\_stringizer](generated/networkx.readwrite.gml.literal_stringizer.html) * [GraphML](graphml.html) * [Format](graphml.html#format) * [read\_graphml](generated/networkx.readwrite.graphml.read_graphml.html) * [write\_graphml](generated/networkx.readwrite.graphml.write_graphml.html) * [generate\_graphml](generated/networkx.readwrite.graphml.generate_graphml.html) * [parse\_graphml](generated/networkx.readwrite.graphml.parse_graphml.html) * [JSON](json_graph.html) * [node\_link\_data](generated/networkx.readwrite.json_graph.node_link_data.html) * [node\_link\_graph](generated/networkx.readwrite.json_graph.node_link_graph.html) * [adjacency\_data](generated/networkx.readwrite.json_graph.adjacency_data.html) * [adjacency\_graph](generated/networkx.readwrite.json_graph.adjacency_graph.html) * [cytoscape\_data](generated/networkx.readwrite.json_graph.cytoscape_data.html) * [cytoscape\_graph](generated/networkx.readwrite.json_graph.cytoscape_graph.html) * [tree\_data](generated/networkx.readwrite.json_graph.tree_data.html) * [tree\_graph](generated/networkx.readwrite.json_graph.tree_graph.html) * [LEDA](leda.html) * [Format](leda.html#format) * [read\_leda](generated/networkx.readwrite.leda.read_leda.html) * [parse\_leda](generated/networkx.readwrite.leda.parse_leda.html) * [SparseGraph6](sparsegraph6.html) * [Graph6](sparsegraph6.html#module-networkx.readwrite.graph6) * [Sparse6](sparsegraph6.html#module-networkx.readwrite.sparse6) * [Pajek](pajek.html) * [Format](pajek.html#format) * [read\_pajek](generated/networkx.readwrite.pajek.read_pajek.html) * [write\_pajek](generated/networkx.readwrite.pajek.write_pajek.html) * [parse\_pajek](generated/networkx.readwrite.pajek.parse_pajek.html) * [generate\_pajek](generated/networkx.readwrite.pajek.generate_pajek.html) * [Matrix Market](matrix_market.html) * [Examples](matrix_market.html#examples) * [Network Text](text.html) * [generate\_network\_text](generated/networkx.readwrite.text.generate_network_text.html) * [write\_network\_text](generated/networkx.readwrite.text.write_network_text.html) --- # Converting to and from other data formats — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Converting to and from other data formats[#](#converting-to-and-from-other-data-formats "Link to this heading") ================================================================================================================ To NetworkX Graph[#](#module-networkx.convert "Link to this heading") ---------------------------------------------------------------------- Functions to convert NetworkX graphs to and from other formats. The preferred way of converting data to a NetworkX graph is through the graph constructor. The constructor calls the to\_networkx\_graph() function which attempts to guess the input type and convert it automatically. ### Examples[#](#examples "Link to this heading") Create a graph with a single edge from a dictionary of dictionaries \>>> d \= {0: {1: 1}} \# dict-of-dicts single edge (0,1) \>>> G \= nx.Graph(d) ### See Also[#](#see-also "Link to this heading") nx\_agraph, nx\_pydot | | | | --- | --- | | [`to_networkx_graph`](generated/networkx.convert.to_networkx_graph.html#networkx.convert.to_networkx_graph "networkx.convert.to_networkx_graph")
(data\[, create\_using, ...\]) | Make a NetworkX graph from a known data structure. | Dictionaries[#](#dictionaries "Link to this heading") ------------------------------------------------------ | | | | --- | --- | | [`to_dict_of_dicts`](generated/networkx.convert.to_dict_of_dicts.html#networkx.convert.to_dict_of_dicts "networkx.convert.to_dict_of_dicts")
(G\[, nodelist, edge\_data\]) | Returns adjacency representation of graph as a dictionary of dictionaries. | | [`from_dict_of_dicts`](generated/networkx.convert.from_dict_of_dicts.html#networkx.convert.from_dict_of_dicts "networkx.convert.from_dict_of_dicts")
(d\[, create\_using, ...\]) | Returns a graph from a dictionary of dictionaries. | Lists[#](#lists "Link to this heading") ---------------------------------------- | | | | --- | --- | | [`to_dict_of_lists`](generated/networkx.convert.to_dict_of_lists.html#networkx.convert.to_dict_of_lists "networkx.convert.to_dict_of_lists")
(G\[, nodelist\]) | Returns adjacency representation of graph as a dictionary of lists. | | [`from_dict_of_lists`](generated/networkx.convert.from_dict_of_lists.html#networkx.convert.from_dict_of_lists "networkx.convert.from_dict_of_lists")
(d\[, create\_using\]) | Returns a graph from a dictionary of lists. | | [`to_edgelist`](generated/networkx.convert.to_edgelist.html#networkx.convert.to_edgelist "networkx.convert.to_edgelist")
(G\[, nodelist\]) | Returns a list of edges in the graph. | | [`from_edgelist`](generated/networkx.convert.from_edgelist.html#networkx.convert.from_edgelist "networkx.convert.from_edgelist")
(edgelist\[, create\_using\]) | Returns a graph from a list of edges. | Numpy[#](#module-networkx.convert_matrix "Link to this heading") ----------------------------------------------------------------- Functions to convert NetworkX graphs to and from common data containers like numpy arrays, scipy sparse arrays, and pandas DataFrames. The preferred way of converting data to a NetworkX graph is through the graph constructor. The constructor calls the [`to_networkx_graph`](generated/networkx.convert.to_networkx_graph.html#networkx.convert.to_networkx_graph "networkx.convert.to_networkx_graph") function which attempts to guess the input type and convert it automatically. ### Examples[#](#id1 "Link to this heading") Create a 10 node random graph from a numpy array \>>> import numpy as np \>>> rng \= np.random.default\_rng() \>>> a \= rng.integers(low\=0, high\=2, size\=(10, 10)) \>>> DG \= nx.from\_numpy\_array(a, create\_using\=nx.DiGraph) or equivalently: \>>> DG \= nx.DiGraph(a) which calls [`from_numpy_array`](generated/networkx.convert_matrix.from_numpy_array.html#networkx.convert_matrix.from_numpy_array "networkx.convert_matrix.from_numpy_array") internally based on the type of `a`. ### See Also[#](#id2 "Link to this heading") nx\_agraph, nx\_pydot | | | | --- | --- | | [`to_numpy_array`](generated/networkx.convert_matrix.to_numpy_array.html#networkx.convert_matrix.to_numpy_array "networkx.convert_matrix.to_numpy_array")
(G\[, nodelist, dtype, order, ...\]) | Returns the graph adjacency matrix as a NumPy array. | | [`from_numpy_array`](generated/networkx.convert_matrix.from_numpy_array.html#networkx.convert_matrix.from_numpy_array "networkx.convert_matrix.from_numpy_array")
(A\[, parallel\_edges, ...\]) | Returns a graph from a 2D NumPy array. | Scipy[#](#scipy "Link to this heading") ---------------------------------------- | | | | --- | --- | | [`to_scipy_sparse_array`](generated/networkx.convert_matrix.to_scipy_sparse_array.html#networkx.convert_matrix.to_scipy_sparse_array "networkx.convert_matrix.to_scipy_sparse_array")
(G\[, nodelist, dtype, ...\]) | Returns the graph adjacency matrix as a SciPy sparse array. | | [`from_scipy_sparse_array`](generated/networkx.convert_matrix.from_scipy_sparse_array.html#networkx.convert_matrix.from_scipy_sparse_array "networkx.convert_matrix.from_scipy_sparse_array")
(A\[, parallel\_edges, ...\]) | Creates a new graph from an adjacency matrix given as a SciPy sparse array. | Pandas[#](#pandas "Link to this heading") ------------------------------------------ | | | | --- | --- | | [`to_pandas_adjacency`](generated/networkx.convert_matrix.to_pandas_adjacency.html#networkx.convert_matrix.to_pandas_adjacency "networkx.convert_matrix.to_pandas_adjacency")
(G\[, nodelist, dtype, ...\]) | Returns the graph adjacency matrix as a Pandas DataFrame. | | [`from_pandas_adjacency`](generated/networkx.convert_matrix.from_pandas_adjacency.html#networkx.convert_matrix.from_pandas_adjacency "networkx.convert_matrix.from_pandas_adjacency")
(df\[, create\_using\]) | Returns a graph from Pandas DataFrame. | | [`to_pandas_edgelist`](generated/networkx.convert_matrix.to_pandas_edgelist.html#networkx.convert_matrix.to_pandas_edgelist "networkx.convert_matrix.to_pandas_edgelist")
(G\[, source, target, ...\]) | Returns the graph edge list as a Pandas DataFrame. | | [`from_pandas_edgelist`](generated/networkx.convert_matrix.from_pandas_edgelist.html#networkx.convert_matrix.from_pandas_edgelist "networkx.convert_matrix.from_pandas_edgelist")
(df\[, source, target, ...\]) | Returns a graph from Pandas DataFrame containing an edge list. | On this page --- # Backends — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Backends[#](#backends "Link to this heading") ============================================== NetworkX can be configured to use separate thrid-party backends to improve performance and add functionality. Backends are optional, installed separately, and can be enabled either directly in the user’s code or through environment variables. Note The interface used by developers creating custom NetworkX backends is receiving frequent updates and improvements. Participating in weekly [NetworkX dispatch meetings](https://scientific-python.org/calendars/networkx.ics) is an excellent way to stay updated and contribute to the ongoing discussions. Docs for backend users[#](#docs-for-backend-users "Link to this heading") -------------------------------------------------------------------------- NetworkX utilizes a plugin-dispatch architecture. A valid NetworkX backend specifies [entry points](https://packaging.python.org/en/latest/specifications/entry-points) , named `networkx.backends` and an optional `networkx.backend_info` when it is installed (not imported). This allows NetworkX to dispatch (redirect) function calls to the backend so the execution flows to the designated backend implementation. This design enhances flexibility and integration, making NetworkX more adaptable and efficient. NetworkX can dispatch to backends **explicitly** (this requires changing code) or **automatically** (this requires setting configuration or environment variables). The best way to use a backend depends on the backend, your use case, and whether you want to automatically convert to or from backend graphs. Automatic conversions of graphs is always opt-in. To explicitly dispatch to a backend, use the `backend=` keyword argument in a dispatchable function. This will convert (and cache by default) input NetworkX graphs to backend graphs and call the backend implementation. Another explicit way to use a backend is to create a backend graph directly–for example, perhaps the backend has its own functions for loading data and creating graphs–and pass that graph to a dispatchable function, which will then call the backend implementation without converting. Using automatic dispatch requires setting configuration options. Every NetworkX configuration may also be set from an environment variable and are processed at the time networkx is imported. The following configuration variables are supported: * `nx.config.backend_priority` (`NETWORKX_BACKEND_PRIORITY` env var), a list of backends, controls dispatchable functions that don’t return graphs such as e.g. `nx.pagerank`. When one of these functions is called with NetworkX graphs as input, the dispatcher iterates over the backends listed in this backend\_priority config and will use the first backend that implements this function. The input NetworkX graphs are converted (and cached by default) to backend graphs. Using this configuration can allow you to use the full flexibility of NetworkX graphs and the performance of backend implementations, but possible downsides are that creating NetworkX graphs, converting to backend graphs, and caching backend graphs may all be expensive. * `nx.config.backend_priority.algos` (`NETWORKX_BACKEND_PRIORITY_ALGOS` env var), can be used instead of `nx.config.backend_priority` (`NETWORKX_BACKEND_PRIORITY` env var) to emphasize that the setting only affects the dispatching of algorithm functions as described above. * `nx.config.backend_priority.generators` (`NETWORKX_BACKEND_PRIORITY_GENERATORS` env var), a list of backends, controls dispatchable functions that return graphs such as nx.from\_pandas\_edgelist and nx.empty\_graph. When one of these functions is called, the first backend listed in this backend\_priority config that implements this function will be used and will return a backend graph. When this backend graph is passed to other dispatchable NetworkX functions, it will use the backend implementation if it exists or raise by default unless nx.config.fallback\_to\_nx is True (default is False). Using this configuration avoids creating NetworkX graphs, which subsequently avoids the need to convert to and cache backend graphs as when using nx.config.backend\_priority.algos, but possible downsides are that the backend graph may not behave the same as a NetworkX graph and the backend may not implement all algorithms that you use, which may break your workflow. * `nx.config.fallback_to_nx` (`NETWORKX_FALLBACK_TO_NX` env var), a boolean (default False), controls what happens when a backend graph is passed to a dispatchable function that is not implemented by that backend. The default behavior when False is to raise. If True, then the backend graph will be converted (and cached by default) to a NetworkX graph and will run with the default NetworkX implementation. Enabling this configuration can allow workflows to complete if the backend does not implement all algorithms used by the workflow, but a possible downside is that it may require converting the input backend graph to a NetworkX graph, which may be expensive. If a backend graph is duck-type compatible as a NetworkX graph, then the backend may choose not to convert to a NetworkX graph and use the incoming graph as-is. * `nx.config.cache_converted_graphs` (`NETWORKX_CACHE_CONVERTED_GRAPHS` env var), a boolean (default True), controls whether graph conversions are cached to G.\_\_networkx\_cache\_\_ or not. Caching can improve performance by avoiding repeated conversions, but it uses more memory. Note Backends _should_ follow the NetworkX backend naming convention. For example, if a backend is named `parallel` and specified using `backend=parallel` or `NETWORKX_BACKEND_PRIORITY=parallel`, the package installed is `nx-parallel`, and we would use `import nx_parallel` if we were to import the backend package directly. Backends are encouraged to document how they recommend to be used and whether their graph types are duck-type compatible as NetworkX graphs. If backend graphs are NetworkX-compatible and you want your workflow to automatically “just work” with a backend–converting and caching if necessary–then use all of the above configurations. Automatically converting graphs is opt-in, and configuration gives the user control. ### Examples:[#](#examples "Link to this heading") Use the `cugraph` backend for every algorithm function it supports. This will allow for fall back to the default NetworkX implementations for algorithm calls not supported by cugraph because graph generator functions are still returning NetworkX graphs. bash> NETWORKX\_BACKEND\_PRIORITY\=cugraph python my\_networkx\_script.py Explicitly use the `parallel` backend for a function call. nx.betweenness\_centrality(G, k\=10, backend\="parallel") Explicitly use the `parallel` backend for a function call by passing an instance of the backend graph type to the function. H \= nx\_parallel.ParallelGraph(G) nx.betweenness\_centrality(H, k\=10) Explicitly use the `parallel` backend and pass additional backend-specific arguments. Here, `get_chunks` is an argument unique to the `parallel` backend. nx.betweenness\_centrality(G, k\=10, backend\="parallel", get\_chunks\=get\_chunks) Automatically dispatch the `cugraph` backend for all NetworkX algorithms and generators, and allow the backend graph object returned from generators to be passed to NetworkX functions the backend does not support. bash> NETWORKX\_BACKEND\_PRIORITY\_ALGOS\=cugraph \\ NETWORKX\_BACKEND\_PRIORITY\_GENERATORS\=cugraph \\ NETWORKX\_FALLBACK\_TO\_NX\=True \\ python my\_networkx\_script.py ### How does this work?[#](#how-does-this-work "Link to this heading") If you’ve looked at functions in the NetworkX codebase, you might have seen the `@nx._dispatchable` decorator on most of the functions. This decorator allows the NetworkX function to dispatch to the corresponding backend function if available. When the decorated function is called, it first checks for a backend to run the function, and if no appropriate backend is specified or available, it runs the NetworkX version of the function. #### Backend Keyword Argument[#](#backend-keyword-argument "Link to this heading") When a decorated function is called with the `backend` kwarg provided, it checks if the specified backend is installed, and loads it. Next it checks whether to convert input graphs by first resolving the backend of each input graph by looking for an attribute named `__networkx_backend__` that holds the backend name for that graph type. If all input graphs backend matches the `backend` kwarg, the backend’s function is called with the original inputs. If any of the input graphs do not match the `backend` kwarg, they are converted to the backend graph type before calling. Exceptions are raised if any step is not possible, e.g. if the backend does not implement this function. #### Finding a Backend[#](#finding-a-backend "Link to this heading") When a decorated function is called without a `backend` kwarg, it tries to find a dispatchable backend function. The backend type of each input graph parameter is resolved (using the `__networkx_backend__` attribute) and if they all agree, that backend’s function is called if possible. Otherwise the backends listed in the config `backend_priority` are considered one at a time in order. If that backend supports the function and can convert the input graphs to its backend type, that backend function is called. Otherwise the next backend is considered. During this process, the backends can provide helpful information to the dispatcher via helper methods in the backend’s interface. Backend methods `can_run` and `should_run` are used by the dispatcher to determine whether to use the backend function. If the number of nodes is small, it might be faster to run the NetworkX version of the function. This is how backends can provide info about whether to run. #### Falling Back to NetworkX[#](#falling-back-to-networkx "Link to this heading") If none of the backends are appropriate, we “fall back” to the NetworkX function. That means we resolve the backends of all input graphs and if all are NetworkX graphs we call the NetworkX function. If any are not NetworkX graphs, we raise an exception unless the `fallback_to_nx` config is set. If it is, we convert all graph types to NetworkX graph types before calling the NetworkX function. #### Functions that mutate the graph[#](#functions-that-mutate-the-graph "Link to this heading") Any function decorated with the option that indicates it mutates the graph goes through a slightly different path to automatically find backends. These functions typically generate a graph, or add attributes or change the graph structure. The config `backend_priority.generators` holds a list of backend names similar to the config `backend_priority`. The process is similar for finding a matching backend. Once found, the backend function is called and a backend graph is returned (instead of a NetworkX graph). You can then use this backend graph in any function supported by the backend. And you can use it for functions not supported by the backend if you set the config `fallback_to_nx` to allow it to convert the backend graph to a NetworkX graph before calling the function. #### Optional keyword arguments[#](#optional-keyword-arguments "Link to this heading") Backends can add optional keyword parameters to NetworkX functions to allow you to control aspects of the backend algorithm. Thus the function signatures can be extended beyond the NetworkX function signature. For example, the `parallel` backend might have a parameter to specify how many CPUs to use. These parameters are collected by the dispatchable decorator code at the start of the function call and used when calling the backend function. #### Existing Backends[#](#existing-backends "Link to this heading") NetworkX does not know all the backends that have been created. In fact, the NetworkX library does not need to know that a backend exists for it to work. As long as the backend package creates the `entry_point`, and provides the correct interface, it will be called when the user requests it using one of the three approaches described above. Some backends have been working with the NetworkX developers to ensure smooth operation. Refer to the [Backends](../backends.html) section to see a list of available backends known to work with the current stable release of NetworkX. ### Introspection and Logging[#](#introspection-and-logging "Link to this heading") Introspection techniques aim to demystify dispatching and backend graph conversion behaviors. The primary way to see what the dispatch machinery is doing is by enabling logging. This can help you verify that the backend you specified is being used. You can enable NetworkX’s backend logger to print to `sys.stderr` like this: import logging nxl \= logging.getLogger("networkx") nxl.addHandler(logging.StreamHandler()) nxl.setLevel(logging.DEBUG) And you can disable it by running this: nxl.setLevel(logging.CRITICAL) Refer to [`logging`](https://docs.python.org/3/library/logging.html#module-logging "(in Python v3.13)") to learn more about the logging facilities in Python. By looking at the `.backends` attribute, you can get the set of all currently installed backends that implement a particular function. For example: \>>> nx.betweenness\_centrality.backends {'parallel'} The function docstring will also show which installed backends support it along with any backend-specific notes and keyword arguments: \>>> help(nx.betweenness\_centrality) ... Backends \-------- parallel : Parallel backend for NetworkX algorithms The parallel computation is implemented by dividing the nodes into chunks and computing betweenness centrality for each chunk concurrently. ... The NetworkX documentation website also includes info about trusted backends of NetworkX in function references. For example, see [`all_pairs_bellman_ford_path_length()`](algorithms/generated/networkx.algorithms.shortest_paths.weighted.all_pairs_bellman_ford_path_length.html#networkx.algorithms.shortest_paths.weighted.all_pairs_bellman_ford_path_length "networkx.algorithms.shortest_paths.weighted.all_pairs_bellman_ford_path_length") . Introspection capabilities are currently limited, but we are working to improve them. We plan to make it easier to answer questions such as: * What happened (and why)? * What _will_ happen (and why)? * Where was time spent (including conversions)? * What is in the cache and how much memory is it using? Transparency is essential to allow for greater understanding, debug-ability, and customization. After all, NetworkX dispatching is extremely flexible and can support advanced workflows with multiple backends and fine-tuned configuration, but introspection can be helpful by describing _when_ and _how_ to evolve your workflow to meet your needs. If you have suggestions for how to improve introspection, please [let us know](https://github.com/networkx/networkx/issues/new) ! Docs for backend developers[#](#docs-for-backend-developers "Link to this heading") ------------------------------------------------------------------------------------ ### Creating a custom backend[#](#creating-a-custom-backend "Link to this heading") 1. Defining a `BackendInterface` object: Note that the `BackendInterface` doesn’t need to must be a class. It can be an instance of a class, or a module as well. You can define the following methods or functions in your backend’s `BackendInterface` object.: 1. `convert_from_nx` and `convert_to_nx` methods or functions are required for backend dispatching to work. The arguments to `convert_from_nx` are: * `G` : NetworkX Graph * `edge_attrs`dict, optional Dictionary mapping edge attributes to default values if missing in `G`. If None, then no edge attributes will be converted and default may be 1. * `node_attrs`: dict, optional Dictionary mapping node attributes to default values if missing in `G`. If None, then no node attributes will be converted. * `preserve_edge_attrs`bool Whether to preserve all edge attributes. * `preserve_node_attrs`bool Whether to preserve all node attributes. * `preserve_graph_attrs`bool Whether to preserve all graph attributes. * `preserve_all_attrs`bool Whether to preserve all graph, node, and edge attributes. * `name`str The name of the algorithm. * `graph_name`str The name of the graph argument being converted. 2. `can_run` (Optional): If your backend only partially implements an algorithm, you can define a `can_run(name, args, kwargs)` function in your `BackendInterface` object that returns True or False indicating whether the backend can run the algorithm with the given arguments or not. Instead of a boolean you can also return a string message to inform the user why that algorithm can’t be run. 3. `should_run` (Optional): A backend may also define `should_run(name, args, kwargs)` that is similar to `can_run`, but answers whether the backend _should_ be run. `should_run` is only run when performing backend graph conversions. Like `can_run`, it receives the original arguments so it can decide whether it should be run by inspecting the arguments. `can_run` runs before `should_run`, so `should_run` may assume `can_run` is True. If not implemented by the backend, `can_run``and ``should_run` are assumed to always return True if the backend implements the algorithm. 4. `on_start_tests` (Optional): A special `on_start_tests(items)` function may be defined by the backend. It will be called with the list of NetworkX tests discovered. Each item is a test object that can be marked as xfail if the backend does not support the test using `item.add_marker(pytest.mark.xfail(reason=...))`. 2. Adding entry points To be discoverable by NetworkX, your package must register an [entry-point](https://packaging.python.org/en/latest/specifications/entry-points) `networkx.backends` in the package’s metadata, with a [key pointing to your dispatch object](https://packaging.python.org/en/latest/guides/creating-and-discovering-plugins/#using-package-metadata) . For example, if you are using `setuptools` to manage your backend package, you can [add the following to your pyproject.toml file](https://setuptools.pypa.io/en/latest/userguide/entry_point.html) : \[project.entry\-points."networkx.backends"\] backend\_name \= "your\_backend\_interface\_object" You can also add the `backend_info` entry-point. It points towards the `get_info` function that returns all the backend information, which is then used to build the “Additional Backend Implementation” box at the end of algorithm’s documentation page. Note that the `get_info` function shouldn’t import your backend package.: \[project.entry\-points."networkx.backend\_info"\] backend\_name \= "your\_get\_info\_function" The `get_info` should return a dictionary with following key-value pairs: * `backend_name`str or None It is the name passed in the `backend` kwarg. * `project`str or None The name of your backend project. * `package`str or None The name of your backend package. * `url`str or None This is the url to either your backend’s codebase or documentation, and will be displayed as a hyperlink to the `backend_name`, in the “Additional backend implementations” section. * `short_summary`str or None One line summary of your backend which will be displayed in the “Additional backend implementations” section. * `default_config`dict A dictionary mapping the backend config parameter names to their default values. This is used to automatically initialize the default configs for all the installed backends at the time of networkx’s import. See also [`Config`](configs.html#networkx.utils.configs.Config "networkx.utils.configs.Config") * `functions`dict or None A dictionary mapping function names to a dictionary of information about the function. The information can include the following keys: * `url` : str or None The url to `function`’s source code or documentation. * `additional_docs` : str or None A short description or note about the backend function’s implementation. * `additional_parameters` : dict or None A dictionary mapping additional parameters headers to their short descriptions. For example: "additional\_parameters": { 'param1 : str, function (default = "chunks")' : "...", 'param2 : int' : "...", } If any of these keys are not present, the corresponding information will not be displayed in the “Additional backend implementations” section on NetworkX docs website. Note that your backend’s docs would only appear on the official NetworkX docs only if your backend is a trusted backend of NetworkX, and is present in the `circleci/config.yml` and `github/workflows/deploy-docs.yml` files in the NetworkX repository. 3. Defining a Backend Graph class The backend must create an object with an attribute `__networkx_backend__` that holds a string with the entry point name: class BackendGraph: \_\_networkx\_backend\_\_ \= "backend\_name" ... A backend graph instance may have a `G.__networkx_cache__` dict to enable caching, and care should be taken to clear the cache when appropriate. ### Testing the Custom backend[#](#testing-the-custom-backend "Link to this heading") To test your custom backend, you can run the NetworkX test suite on your backend. This also ensures that the custom backend is compatible with NetworkX’s API. The following steps will help you run the tests: 1. Setting Backend Environment Variables: * `NETWORKX_TEST_BACKEND` : Setting this to your backend’s `backend_name` will let NetworkX’s dispatch machinery to automatically convert a regular NetworkX `Graph`, `DiGraph`, `MultiGraph`, etc. to their backend equivalents, using `your_backend_interface_object.convert_from_nx(G, ...)` function. * `NETWORKX_FALLBACK_TO_NX` (default=False) : Setting this variable to [`True`](https://docs.python.org/3/library/constants.html#True "(in Python v3.13)") will instruct tests to use a NetworkX `Graph` for algorithms not implemented by your custom backend. Setting this to [`False`](https://docs.python.org/3/library/constants.html#False "(in Python v3.13)") will only run the tests for algorithms implemented by your custom backend and tests for other algorithms will `xfail`. 2. Running Tests: You can invoke NetworkX tests for your custom backend with the following commands: NETWORKX\_TEST\_BACKEND\= NETWORKX\_FALLBACK\_TO\_NX\=True \# or False pytest \--pyargs networkx ### How tests are run?[#](#how-tests-are-run "Link to this heading") 1. While dispatching to the backend implementation the `_convert_and_call` function is used and while testing the `_convert_and_call_for_tests` function is used. Other than testing it also checks for functions that return numpy scalars, and for functions that return graphs it runs the backend implementation and the networkx implementation and then converts the backend graph into a NetworkX graph and then compares them, and returns the networkx graph. This can be regarded as (pragmatic) technical debt. We may replace these checks in the future. 2. Conversions while running tests: * Convert NetworkX graphs using `.convert_from_nx(G, ...)` into the backend graph. * Pass the backend graph objects to the backend implementation of the algorithm. * Convert the result back to a form expected by NetworkX tests using `.convert_to_nx(result, ...)`. * For nx\_loopback, the graph is copied using the dispatchable metadata 3. Dispatchable algorithms that are not implemented by the backend will cause a `pytest.xfail`, when the `NETWORKX_FALLBACK_TO_NX` environment variable is set to `False`, giving some indication that not all tests are running, while avoiding causing an explicit failure. | | | | --- | --- | | [`_dispatchable`](generated/networkx.utils.backends._dispatchable.html#networkx.utils.backends._dispatchable "networkx.utils.backends._dispatchable")
(\[func, name, graphs, ...\]) | A decorator function that is used to redirect the execution of `func` function to its backend implementation. | On this page --- # Relabeling nodes — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Relabeling nodes[#](#relabeling-nodes "Link to this heading") ============================================================== Relabeling[#](#module-networkx.relabel "Link to this heading") --------------------------------------------------------------- | | | | --- | --- | | [`convert_node_labels_to_integers`](generated/networkx.relabel.convert_node_labels_to_integers.html#networkx.relabel.convert_node_labels_to_integers "networkx.relabel.convert_node_labels_to_integers")
(G\[, ...\]) | Returns a copy of the graph G with the nodes relabeled using consecutive integers. | | [`relabel_nodes`](generated/networkx.relabel.relabel_nodes.html#networkx.relabel.relabel_nodes "networkx.relabel.relabel_nodes")
(G, mapping\[, copy\]) | Relabel the nodes of the graph G according to a given mapping. | On this page --- # Randomness — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Randomness[#](#randomness "Link to this heading") ================================================== Random Number Generators (RNGs) are often used when generating, drawing and computing properties or manipulating networks. NetworkX provides functions which use one of two standard RNGs: NumPy’s package [`numpy.random`](https://numpy.org/doc/stable/reference/random/index.html#module-numpy.random "(in NumPy v2.1)") or Python’s built-in package [`random`](https://docs.python.org/3/library/random.html#module-random "(in Python v3.13)") . They each provide the same algorithm for generating numbers (Mersenne Twister). Their interfaces are similar (dangerously similar) and yet distinct. They each provide a global default instance of their generator that is shared by all programs in a single session. For the most part you can use the RNGs as NetworkX has them set up and you’ll get reasonable pseudorandom results (results that are statistically random, but created in a deterministic manner). Sometimes you want more control over how the numbers are generated. In particular, you need to set the `seed` of the generator to make your results reproducible – either for scientific publication or for debugging. Both RNG packages have easy functions to set the seed to any integer, thus determining the subsequent generated values. Since this package (and many others) use both RNGs you may need to set the `seed` of both RNGs. Even if we strictly only used one of the RNGs, you may find yourself using another package that uses the other. Setting the state of the two global RNGs is as simple setting the seed of each RNG to an arbitrary integer: \>>> import random \>>> random.seed(246) \# or any integer \>>> import numpy \>>> numpy.random.seed(4812) Many users will be satisfied with this level of control. For people who want even more control, we include an optional argument to functions that use an RNG. This argument is called `seed`, but determines more than the seed of the RNG. It tells the function which RNG package to use, and whether to use a global or local RNG. \>>> from networkx import path\_graph, random\_layout \>>> G \= path\_graph(9) \>>> pos \= random\_layout(G, seed\=None) \# use (either) global default RNG \>>> pos \= random\_layout(G, seed\=42) \# local RNG just for this call \>>> pos \= random\_layout(G, seed\=numpy.random) \# use numpy global RNG \>>> random\_state \= numpy.random.RandomState(42) \>>> pos \= random\_layout(G, seed\=random\_state) \# use/reuse your own RNG Each NetworkX function that uses an RNG was written with one RNG package in mind. It either uses [`random`](https://docs.python.org/3/library/random.html#module-random "(in Python v3.13)") or [`numpy.random`](https://numpy.org/doc/stable/reference/random/index.html#module-numpy.random "(in NumPy v2.1)") by default. But some users want to only use a single RNG for all their code. This `seed` argument provides a mechanism so that any function can use a [`numpy.random`](https://numpy.org/doc/stable/reference/random/index.html#module-numpy.random "(in NumPy v2.1)") RNG even if the function is written for [`random`](https://docs.python.org/3/library/random.html#module-random "(in Python v3.13)") . It works as follows. The default behavior (when `seed=None`) is to use the global RNG for the function’s preferred package. If seed is set to an integer value, a local RNG is created with the indicated seed value and is used for the duration of that function (including any calls to other functions) and then discarded. Alternatively, you can specify `seed=numpy.random` to ensure that the global numpy RNG is used whether the function expects it or not. Finally, you can provide a numpy RNG to be used by the function. The RNG is then available to use in other functions or even other package like sklearn. In this way you can use a single RNG for all random numbers in your project. While it is possible to assign `seed` a [`random`](https://docs.python.org/3/library/random.html#module-random "(in Python v3.13)") \-style RNG for NetworkX functions written for the [`random`](https://docs.python.org/3/library/random.html#module-random "(in Python v3.13)") package API, the numpy RNG interface has too many nice features for us to ensure a [`random`](https://docs.python.org/3/library/random.html#module-random "(in Python v3.13)") \-style RNG will work in all functions. In practice, you can do most things using only [`random`](https://docs.python.org/3/library/random.html#module-random "(in Python v3.13)") RNGs (useful if numpy is not available). But your experience will be richer if numpy is available. To summarize, you can easily ignore the `seed` argument and use the global RNGs. You can specify to use only the numpy global RNG with `seed=numpy.random`. You can use a local RNG by providing an integer seed value. And you can provide your own numpy RNG, reusing it for all functions. It is easier to use numpy RNGs if you want a single RNG for your computations. --- # Welcome to nx-guides! — NetworkX Notebooks [Skip to main content](#main-content) Back to top Ctrl+K [![NetworkX Notebooks - Home](_static/networkx_banner.svg) ![NetworkX Notebooks - Home](_static/networkx_banner.svg)](#) * [GitHub](https://github.com/networkx/nx-guides/ "GitHub") Search Ctrl+K * [Repository](https://github.com/networkx/nx-guides "Source repository") * [Suggest edit](https://github.com/networkx/nx-guides/edit/main/site/index.md "Suggest edit") * [Open issue](https://github.com/networkx/nx-guides/issues/new?title=Issue%20on%20page%20%2Findex.html&body=Your%20issue%20content%20here. "Open an issue") * [.md](_sources/index.md "Download source file") * .pdf Welcome to nx-guides! ===================== Contents -------- Welcome to nx-guides![#](#welcome-to-nx-guides "Link to this heading") ======================================================================= [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/networkx/nx-guides/main?urlpath=lab/tree/content) This site provides educational materials officially developed and curated by the NetworkX community. The goal of the repository is to provide high-quality educational resources for learning about network analysis and graph theory with NetworkX. Examples include: * Long-form narrative documentation, such as tutorials * In-depth examinations of common graph and network algorithms and their implementations in NetworkX * Demonstrations or domain-specific applications of NetworkX highlighting best-practices for network analysis. About[#](#about "Link to this heading") ---------------------------------------- The educational materials are in the form of [markdown-based Jupyter notebooks](https://myst-nb.readthedocs.io/en/latest/authoring/text-notebooks.html) , so everything is interactive! You can follow along yourself: 1. _on binder_, by clicking on the launch button at the top of this page, or the rocket icon in the upper-right corner of any of the pages, or 2. _locally_, by cloning the repository (see the octocat icon above) and running `jupyter notebook`. Contents[#](#contents "Link to this heading") ---------------------------------------------- * [Algorithms](content/algorithms/index.html) * [Graph Generators](content/generators/index.html) * [Facebook Network Analysis](content/exploratory_notebooks/facebook_notebook.html) * [Contributors Guide](content/contributing.html) Contents --- # Utilities — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Utilities[#](#module-networkx.utils "Link to this heading") ============================================================ Helper Functions[#](#module-networkx.utils.misc "Link to this heading") ------------------------------------------------------------------------ Miscellaneous Helpers for NetworkX. These are not imported into the base networkx namespace but can be accessed, for example, as \>>> import networkx \>>> networkx.utils.make\_list\_of\_ints({1, 2, 3}) \[1, 2, 3\] \>>> networkx.utils.arbitrary\_element({5, 1, 7}) 1 | | | | --- | --- | | [`arbitrary_element`](generated/networkx.utils.misc.arbitrary_element.html#networkx.utils.misc.arbitrary_element "networkx.utils.misc.arbitrary_element")
(iterable) | Returns an arbitrary element of `iterable` without removing it. | | [`flatten`](generated/networkx.utils.misc.flatten.html#networkx.utils.misc.flatten "networkx.utils.misc.flatten")
(obj\[, result\]) | Return flattened version of (possibly nested) iterable object. | | [`make_list_of_ints`](generated/networkx.utils.misc.make_list_of_ints.html#networkx.utils.misc.make_list_of_ints "networkx.utils.misc.make_list_of_ints")
(sequence) | Return list of ints from sequence of integral numbers. | | [`dict_to_numpy_array`](generated/networkx.utils.misc.dict_to_numpy_array.html#networkx.utils.misc.dict_to_numpy_array "networkx.utils.misc.dict_to_numpy_array")
(d\[, mapping\]) | Convert a dictionary of dictionaries to a numpy array with optional mapping. | | [`pairwise`](generated/networkx.utils.misc.pairwise.html#networkx.utils.misc.pairwise "networkx.utils.misc.pairwise")
(iterable\[, cyclic\]) | s -> (s0, s1), (s1, s2), (s2, s3), ... | | [`groups`](generated/networkx.utils.misc.groups.html#networkx.utils.misc.groups "networkx.utils.misc.groups")
(many\_to\_one) | Converts a many-to-one mapping into a one-to-many mapping. | | [`create_random_state`](generated/networkx.utils.misc.create_random_state.html#networkx.utils.misc.create_random_state "networkx.utils.misc.create_random_state")
(\[random\_state\]) | Returns a numpy.random.RandomState or numpy.random.Generator instance depending on input. | | [`create_py_random_state`](generated/networkx.utils.misc.create_py_random_state.html#networkx.utils.misc.create_py_random_state "networkx.utils.misc.create_py_random_state")
(\[random\_state\]) | Returns a random.Random instance depending on input. | | [`nodes_equal`](generated/networkx.utils.misc.nodes_equal.html#networkx.utils.misc.nodes_equal "networkx.utils.misc.nodes_equal")
(nodes1, nodes2) | Check if nodes are equal. | | [`edges_equal`](generated/networkx.utils.misc.edges_equal.html#networkx.utils.misc.edges_equal "networkx.utils.misc.edges_equal")
(edges1, edges2) | Check if edges are equal. | | [`graphs_equal`](generated/networkx.utils.misc.graphs_equal.html#networkx.utils.misc.graphs_equal "networkx.utils.misc.graphs_equal")
(graph1, graph2) | Check if graphs are equal. | Data Structures and Algorithms[#](#module-networkx.utils.union_find "Link to this heading") -------------------------------------------------------------------------------------------- Union-find data structure. | | | | --- | --- | | [`UnionFind.union`](generated/networkx.utils.union_find.UnionFind.union.html#networkx.utils.union_find.UnionFind.union "networkx.utils.union_find.UnionFind.union")
(\*objects) | Find the sets containing the objects and merge them all. | Random Sequence Generators[#](#module-networkx.utils.random_sequence "Link to this heading") --------------------------------------------------------------------------------------------- Utilities for generating random numbers, random sequences, and random selections. | | | | --- | --- | | [`powerlaw_sequence`](generated/networkx.utils.random_sequence.powerlaw_sequence.html#networkx.utils.random_sequence.powerlaw_sequence "networkx.utils.random_sequence.powerlaw_sequence")
(n\[, exponent, seed\]) | Return sample sequence of length n from a power law distribution. | | [`cumulative_distribution`](generated/networkx.utils.random_sequence.cumulative_distribution.html#networkx.utils.random_sequence.cumulative_distribution "networkx.utils.random_sequence.cumulative_distribution")
(distribution) | Returns normalized cumulative distribution from discrete distribution. | | [`discrete_sequence`](generated/networkx.utils.random_sequence.discrete_sequence.html#networkx.utils.random_sequence.discrete_sequence "networkx.utils.random_sequence.discrete_sequence")
(n\[, distribution, ...\]) | Return sample sequence of length n from a given discrete distribution or discrete cumulative distribution. | | [`zipf_rv`](generated/networkx.utils.random_sequence.zipf_rv.html#networkx.utils.random_sequence.zipf_rv "networkx.utils.random_sequence.zipf_rv")
(alpha\[, xmin, seed\]) | Returns a random value chosen from the Zipf distribution. | | [`random_weighted_sample`](generated/networkx.utils.random_sequence.random_weighted_sample.html#networkx.utils.random_sequence.random_weighted_sample "networkx.utils.random_sequence.random_weighted_sample")
(mapping, k\[, seed\]) | Returns k items without replacement from a weighted sample. | | [`weighted_choice`](generated/networkx.utils.random_sequence.weighted_choice.html#networkx.utils.random_sequence.weighted_choice "networkx.utils.random_sequence.weighted_choice")
(mapping\[, seed\]) | Returns a single element from a weighted sample. | Decorators[#](#module-networkx.utils.decorators "Link to this heading") ------------------------------------------------------------------------ | | | | --- | --- | | [`open_file`](generated/networkx.utils.decorators.open_file.html#networkx.utils.decorators.open_file "networkx.utils.decorators.open_file")
(path\_arg\[, mode\]) | Decorator to ensure clean opening and closing of files. | | [`not_implemented_for`](generated/networkx.utils.decorators.not_implemented_for.html#networkx.utils.decorators.not_implemented_for "networkx.utils.decorators.not_implemented_for")
(\*graph\_types) | Decorator to mark algorithms as not implemented | | [`nodes_or_number`](generated/networkx.utils.decorators.nodes_or_number.html#networkx.utils.decorators.nodes_or_number "networkx.utils.decorators.nodes_or_number")
(which\_args) | Decorator to allow number of nodes or container of nodes. | | [`np_random_state`](generated/networkx.utils.decorators.np_random_state.html#networkx.utils.decorators.np_random_state "networkx.utils.decorators.np_random_state")
(random\_state\_argument) | Decorator to generate a numpy RandomState or Generator instance. | | [`py_random_state`](generated/networkx.utils.decorators.py_random_state.html#networkx.utils.decorators.py_random_state "networkx.utils.decorators.py_random_state")
(random\_state\_argument) | Decorator to generate a random.Random instance (or equiv). | | [`argmap`](generated/networkx.utils.decorators.argmap.html#networkx.utils.decorators.argmap "networkx.utils.decorators.argmap")
(func, \*args\[, try\_finally\]) | A decorator to apply a map to arguments before calling the function | Cuthill-Mckee Ordering[#](#module-networkx.utils.rcm "Link to this heading") ----------------------------------------------------------------------------- Cuthill-McKee ordering of graph nodes to produce sparse matrices | | | | --- | --- | | [`cuthill_mckee_ordering`](generated/networkx.utils.rcm.cuthill_mckee_ordering.html#networkx.utils.rcm.cuthill_mckee_ordering "networkx.utils.rcm.cuthill_mckee_ordering")
(G\[, heuristic\]) | Generate an ordering (permutation) of the graph nodes to make a sparse matrix. | | [`reverse_cuthill_mckee_ordering`](generated/networkx.utils.rcm.reverse_cuthill_mckee_ordering.html#networkx.utils.rcm.reverse_cuthill_mckee_ordering "networkx.utils.rcm.reverse_cuthill_mckee_ordering")
(G\[, heuristic\]) | Generate an ordering (permutation) of the graph nodes to make a sparse matrix. | Mapped Queue[#](#module-networkx.utils.mapped_queue "Link to this heading") ---------------------------------------------------------------------------- Priority queue class with updatable priorities. | | | | --- | --- | | [`MappedQueue`](generated/networkx.utils.mapped_queue.MappedQueue.html#networkx.utils.mapped_queue.MappedQueue "networkx.utils.mapped_queue.MappedQueue")
(\[data\]) | The MappedQueue class implements a min-heap with removal and update-priority. | On this page --- # Glossary — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Glossary[#](#glossary "Link to this heading") ============================================== dictionary[#](#term-dictionary "Link to this term") A Python dictionary maps keys to values. Also known as “hashes”, or “associative arrays” in other programming languages. See [the Python tutorial on dictionaries](https://docs.python.org/3/tutorial/datastructures.html#tut-dictionaries "(in Python v3.13)") . edge[#](#term-edge "Link to this term") Edges are either two-tuples of nodes `(u, v)` or three tuples of nodes with an edge attribute dictionary `(u, v, dict)`. ebunch[#](#term-ebunch "Link to this term") An iterable container of edge tuples like a list, iterator, or file. edge attribute[#](#term-edge-attribute "Link to this term") Edges can have arbitrary Python objects assigned as attributes by using keyword/value pairs when adding an edge assigning to the `G.edges[u][v]` attribute dictionary for the specified edge _u_\-_v_. nbunch[#](#term-nbunch "Link to this term") An nbunch is a single node, container of nodes or [`None`](https://docs.python.org/3/library/constants.html#None "(in Python v3.13)") (representing all nodes). It can be a list, set, graph, etc. To filter an nbunch so that only nodes actually in `G` appear, use `G.nbunch_iter(nbunch)`. If the nbunch is a container or iterable that is not itself a node in the graph, then it will be treated as an iterable of nodes, for instance, when nbunch is a string or a tuple: \>>> import networkx as nx \>>> G \= nx.DiGraph() \>>> G.add\_edges\_from(\[("b", "c"), ("a", "ab"), ("ab", "c")\]) \>>> G.edges("ab") OutEdgeDataView(\[('ab', 'c')\]) Since “ab” is a node in G, it is treated as a single node: \>>> G.edges("bc") OutEdgeDataView(\[('b', 'c')\]) Since “bc” is not a node in G, it is treated as an iterator: \>>> G.edges(\["bc"\]) OutEdgeDataView(\[\]) If “bc” is wrapped in a list, the list is the iterable and “bc” is treated as a single node. That is, if the nbunch is an iterable of iterables, the inner iterables will always be treated as nodes: \>>> G.edges("de") OutEdgeDataView(\[\]) When nbunch is an iterator that is not itself a node and none of its elements are nodes, then the edge view suite of methods return an empty edge view. node[#](#term-node "Link to this term") A node can be any hashable Python object except None. node attribute[#](#term-node-attribute "Link to this term") Nodes can have arbitrary Python objects assigned as attributes by using keyword/value pairs when adding a node or assigning to the `G.nodes[n]` attribute dictionary for the specified node `n`. --- # Exceptions — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Exceptions[#](#module-networkx.exception "Link to this heading") ================================================================= Base exceptions and errors for NetworkX. _class_ NetworkXException[\[source\]](../_modules/networkx/exception.html#NetworkXException) [#](#networkx.NetworkXException "Link to this definition") Base class for exceptions in NetworkX. _class_ NetworkXError[\[source\]](../_modules/networkx/exception.html#NetworkXError) [#](#networkx.NetworkXError "Link to this definition") Exception for a serious error in NetworkX _class_ NetworkXPointlessConcept[\[source\]](../_modules/networkx/exception.html#NetworkXPointlessConcept) [#](#networkx.NetworkXPointlessConcept "Link to this definition") Raised when a null graph is provided as input to an algorithm that cannot use it. The null graph is sometimes considered a pointless concept [\[1\]](#r24f86977d036-1) , thus the name of the exception. Notes Null graphs and empty graphs are often used interchangeably but they are well defined in NetworkX. An `empty_graph` is a graph with `n` nodes and 0 edges, and a `null_graph` is a graph with 0 nodes and 0 edges. References \[[1](#id1)\ \] Harary, F. and Read, R. “Is the Null Graph a Pointless Concept?” In Graphs and Combinatorics Conference, George Washington University. New York: Springer-Verlag, 1973. _class_ NetworkXAlgorithmError[\[source\]](../_modules/networkx/exception.html#NetworkXAlgorithmError) [#](#networkx.NetworkXAlgorithmError "Link to this definition") Exception for unexpected termination of algorithms. _class_ NetworkXUnfeasible[\[source\]](../_modules/networkx/exception.html#NetworkXUnfeasible) [#](#networkx.NetworkXUnfeasible "Link to this definition") Exception raised by algorithms trying to solve a problem instance that has no feasible solution. _class_ NetworkXNoPath[\[source\]](../_modules/networkx/exception.html#NetworkXNoPath) [#](#networkx.NetworkXNoPath "Link to this definition") Exception for algorithms that should return a path when running on graphs where such a path does not exist. _class_ NetworkXNoCycle[\[source\]](../_modules/networkx/exception.html#NetworkXNoCycle) [#](#networkx.NetworkXNoCycle "Link to this definition") Exception for algorithms that should return a cycle when running on graphs where such a cycle does not exist. _class_ NodeNotFound[\[source\]](../_modules/networkx/exception.html#NodeNotFound) [#](#networkx.NodeNotFound "Link to this definition") Exception raised if requested node is not present in the graph _class_ HasACycle[\[source\]](../_modules/networkx/exception.html#HasACycle) [#](#networkx.HasACycle "Link to this definition") Raised if a graph has a cycle when an algorithm expects that it will have no cycles. _class_ NetworkXUnbounded[\[source\]](../_modules/networkx/exception.html#NetworkXUnbounded) [#](#networkx.NetworkXUnbounded "Link to this definition") Exception raised by algorithms trying to solve a maximization or a minimization problem instance that is unbounded. _class_ NetworkXNotImplemented[\[source\]](../_modules/networkx/exception.html#NetworkXNotImplemented) [#](#networkx.NetworkXNotImplemented "Link to this definition") Exception raised by algorithms not implemented for a type of graph. _class_ AmbiguousSolution[\[source\]](../_modules/networkx/exception.html#AmbiguousSolution) [#](#networkx.AmbiguousSolution "Link to this definition") Raised if more than one valid solution exists for an intermediary step of an algorithm. In the face of ambiguity, refuse the temptation to guess. This may occur, for example, when trying to determine the bipartite node sets in a disconnected bipartite graph when computing bipartite matchings. _class_ ExceededMaxIterations[\[source\]](../_modules/networkx/exception.html#ExceededMaxIterations) [#](#networkx.ExceededMaxIterations "Link to this definition") Raised if a loop iterates too many times without breaking. This may occur, for example, in an algorithm that computes progressively better approximations to a value but exceeds an iteration bound specified by the user. _class_ PowerIterationFailedConvergence(_num\_iterations_, _\*args_, _\*\*kw_)[\[source\]](../_modules/networkx/exception.html#PowerIterationFailedConvergence) [#](#networkx.PowerIterationFailedConvergence "Link to this definition") Raised when the power iteration method fails to converge within a specified iteration limit. `num_iterations` is the number of iterations that have been completed when this exception was raised. On this page --- # Drawing — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Drawing[#](#drawing "Link to this heading") ============================================ NetworkX provides basic functionality for visualizing graphs, but its main goal is to enable graph analysis rather than perform graph visualization. In the future, graph visualization functionality may be removed from NetworkX or only available as an add-on package. Proper graph visualization is hard, and we highly recommend that people visualize their graphs with tools dedicated to that task. Notable examples of dedicated and fully-featured graph visualization tools are [Cytoscape](http://www.cytoscape.org/) , [Gephi](https://gephi.org/) , [Graphviz](http://www.graphviz.org/) and, for [LaTeX](http://www.latex-project.org/) typesetting, [PGF/TikZ](https://sourceforge.net/projects/pgf/) . To use these and other such tools, you should export your NetworkX graph into a format that can be read by those tools. For example, Cytoscape can read the GraphML format, and so, `networkx.write_graphml(G, path)` might be an appropriate choice. More information on the features provided here are available at * matplotlib: [http://matplotlib.org/](http://matplotlib.org/) * pygraphviz: [http://pygraphviz.github.io/](http://pygraphviz.github.io/) Matplotlib[#](#module-networkx.drawing.nx_pylab "Link to this heading") ------------------------------------------------------------------------ Draw networks with matplotlib. ### Examples[#](#examples "Link to this heading") \>>> G \= nx.complete\_graph(5) \>>> nx.draw(G) ### See Also[#](#see-also "Link to this heading") > * [matplotlib](https://matplotlib.org/stable/index.html "(in Matplotlib v3.9.2)") > > * [`matplotlib.pyplot.scatter()`](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.scatter.html#matplotlib.pyplot.scatter "(in Matplotlib v3.9.2)") > > * [`matplotlib.patches.FancyArrowPatch`](https://matplotlib.org/stable/api/_as_gen/matplotlib.patches.FancyArrowPatch.html#matplotlib.patches.FancyArrowPatch "(in Matplotlib v3.9.2)") > | | | | --- | --- | | [`draw`](generated/networkx.drawing.nx_pylab.draw.html#networkx.drawing.nx_pylab.draw "networkx.drawing.nx_pylab.draw")
(G\[, pos, ax\]) | Draw the graph G with Matplotlib. | | [`draw_networkx`](generated/networkx.drawing.nx_pylab.draw_networkx.html#networkx.drawing.nx_pylab.draw_networkx "networkx.drawing.nx_pylab.draw_networkx")
(G\[, pos, arrows, with\_labels\]) | Draw the graph G using Matplotlib. | | [`draw_networkx_nodes`](generated/networkx.drawing.nx_pylab.draw_networkx_nodes.html#networkx.drawing.nx_pylab.draw_networkx_nodes "networkx.drawing.nx_pylab.draw_networkx_nodes")
(G, pos\[, nodelist, ...\]) | Draw the nodes of the graph G. | | [`draw_networkx_edges`](generated/networkx.drawing.nx_pylab.draw_networkx_edges.html#networkx.drawing.nx_pylab.draw_networkx_edges "networkx.drawing.nx_pylab.draw_networkx_edges")
(G, pos\[, edgelist, ...\]) | Draw the edges of the graph G. | | [`draw_networkx_labels`](generated/networkx.drawing.nx_pylab.draw_networkx_labels.html#networkx.drawing.nx_pylab.draw_networkx_labels "networkx.drawing.nx_pylab.draw_networkx_labels")
(G, pos\[, labels, ...\]) | Draw node labels on the graph G. | | [`draw_networkx_edge_labels`](generated/networkx.drawing.nx_pylab.draw_networkx_edge_labels.html#networkx.drawing.nx_pylab.draw_networkx_edge_labels "networkx.drawing.nx_pylab.draw_networkx_edge_labels")
(G, pos\[, ...\]) | Draw edge labels. | | [`draw_circular`](generated/networkx.drawing.nx_pylab.draw_circular.html#networkx.drawing.nx_pylab.draw_circular "networkx.drawing.nx_pylab.draw_circular")
(G, \*\*kwargs) | Draw the graph `G` with a circular layout. | | [`draw_kamada_kawai`](generated/networkx.drawing.nx_pylab.draw_kamada_kawai.html#networkx.drawing.nx_pylab.draw_kamada_kawai "networkx.drawing.nx_pylab.draw_kamada_kawai")
(G, \*\*kwargs) | Draw the graph `G` with a Kamada-Kawai force-directed layout. | | [`draw_planar`](generated/networkx.drawing.nx_pylab.draw_planar.html#networkx.drawing.nx_pylab.draw_planar "networkx.drawing.nx_pylab.draw_planar")
(G, \*\*kwargs) | Draw a planar networkx graph `G` with planar layout. | | [`draw_random`](generated/networkx.drawing.nx_pylab.draw_random.html#networkx.drawing.nx_pylab.draw_random "networkx.drawing.nx_pylab.draw_random")
(G, \*\*kwargs) | Draw the graph `G` with a random layout. | | [`draw_spectral`](generated/networkx.drawing.nx_pylab.draw_spectral.html#networkx.drawing.nx_pylab.draw_spectral "networkx.drawing.nx_pylab.draw_spectral")
(G, \*\*kwargs) | Draw the graph `G` with a spectral 2D layout. | | [`draw_spring`](generated/networkx.drawing.nx_pylab.draw_spring.html#networkx.drawing.nx_pylab.draw_spring "networkx.drawing.nx_pylab.draw_spring")
(G, \*\*kwargs) | Draw the graph `G` with a spring layout. | | [`draw_shell`](generated/networkx.drawing.nx_pylab.draw_shell.html#networkx.drawing.nx_pylab.draw_shell "networkx.drawing.nx_pylab.draw_shell")
(G\[, nlist\]) | Draw networkx graph `G` with shell layout. | Graphviz AGraph (dot)[#](#module-networkx.drawing.nx_agraph "Link to this heading") ------------------------------------------------------------------------------------ Interface to pygraphviz AGraph class. ### Examples[#](#id2 "Link to this heading") \>>> G \= nx.complete\_graph(5) \>>> A \= nx.nx\_agraph.to\_agraph(G) \>>> H \= nx.nx\_agraph.from\_agraph(A) ### See Also[#](#id3 "Link to this heading") > * Pygraphviz: [http://pygraphviz.github.io/](http://pygraphviz.github.io/) > > * Graphviz: [https://www.graphviz.org](https://www.graphviz.org) > > * DOT Language: [http://www.graphviz.org/doc/info/lang.html](http://www.graphviz.org/doc/info/lang.html) > | | | | --- | --- | | [`from_agraph`](generated/networkx.drawing.nx_agraph.from_agraph.html#networkx.drawing.nx_agraph.from_agraph "networkx.drawing.nx_agraph.from_agraph")
(A\[, create\_using\]) | Returns a NetworkX Graph or DiGraph from a PyGraphviz graph. | | [`to_agraph`](generated/networkx.drawing.nx_agraph.to_agraph.html#networkx.drawing.nx_agraph.to_agraph "networkx.drawing.nx_agraph.to_agraph")
(N) | Returns a pygraphviz graph from a NetworkX graph N. | | [`write_dot`](generated/networkx.drawing.nx_agraph.write_dot.html#networkx.drawing.nx_agraph.write_dot "networkx.drawing.nx_agraph.write_dot")
(G, path) | Write NetworkX graph G to Graphviz dot format on path. | | [`read_dot`](generated/networkx.drawing.nx_agraph.read_dot.html#networkx.drawing.nx_agraph.read_dot "networkx.drawing.nx_agraph.read_dot")
(path) | Returns a NetworkX graph from a dot file on path. | | [`graphviz_layout`](generated/networkx.drawing.nx_agraph.graphviz_layout.html#networkx.drawing.nx_agraph.graphviz_layout "networkx.drawing.nx_agraph.graphviz_layout")
(G\[, prog, root, args\]) | Create node positions for G using Graphviz. | | [`pygraphviz_layout`](generated/networkx.drawing.nx_agraph.pygraphviz_layout.html#networkx.drawing.nx_agraph.pygraphviz_layout "networkx.drawing.nx_agraph.pygraphviz_layout")
(G\[, prog, root, args\]) | Create node positions for G using Graphviz. | Graphviz with pydot[#](#module-networkx.drawing.nx_pydot "Link to this heading") --------------------------------------------------------------------------------- Import and export NetworkX graphs in Graphviz dot format using pydot. Either this module or nx\_agraph can be used to interface with graphviz. ### Examples[#](#id4 "Link to this heading") \>>> G \= nx.complete\_graph(5) \>>> PG \= nx.nx\_pydot.to\_pydot(G) \>>> H \= nx.nx\_pydot.from\_pydot(PG) ### See Also[#](#id5 "Link to this heading") > * pydot: [erocarrera/pydot](https://github.com/erocarrera/pydot) > > * Graphviz: [https://www.graphviz.org](https://www.graphviz.org) > > * DOT Language: [http://www.graphviz.org/doc/info/lang.html](http://www.graphviz.org/doc/info/lang.html) > | | | | --- | --- | | [`from_pydot`](generated/networkx.drawing.nx_pydot.from_pydot.html#networkx.drawing.nx_pydot.from_pydot "networkx.drawing.nx_pydot.from_pydot")
(P) | Returns a NetworkX graph from a Pydot graph. | | [`to_pydot`](generated/networkx.drawing.nx_pydot.to_pydot.html#networkx.drawing.nx_pydot.to_pydot "networkx.drawing.nx_pydot.to_pydot")
(N) | Returns a pydot graph from a NetworkX graph N. | | [`write_dot`](generated/networkx.drawing.nx_pydot.write_dot.html#networkx.drawing.nx_pydot.write_dot "networkx.drawing.nx_pydot.write_dot")
(G, path) | Write NetworkX graph G to Graphviz dot format on path. | | [`read_dot`](generated/networkx.drawing.nx_pydot.read_dot.html#networkx.drawing.nx_pydot.read_dot "networkx.drawing.nx_pydot.read_dot")
(path) | Returns a NetworkX `MultiGraph` or `MultiDiGraph` from the dot file with the passed path. | | [`graphviz_layout`](generated/networkx.drawing.nx_pydot.graphviz_layout.html#networkx.drawing.nx_pydot.graphviz_layout "networkx.drawing.nx_pydot.graphviz_layout")
(G\[, prog, root\]) | Create node positions using Pydot and Graphviz. | | [`pydot_layout`](generated/networkx.drawing.nx_pydot.pydot_layout.html#networkx.drawing.nx_pydot.pydot_layout "networkx.drawing.nx_pydot.pydot_layout")
(G\[, prog, root\]) | Create node positions using `pydot` and Graphviz. | Graph Layout[#](#module-networkx.drawing.layout "Link to this heading") ------------------------------------------------------------------------ Node positioning algorithms for graph drawing. For [`random_layout()`](generated/networkx.drawing.layout.random_layout.html#networkx.drawing.layout.random_layout "networkx.drawing.layout.random_layout") the possible resulting shape is a square of side \[0, scale\] (default: \[0, 1\]) Changing `center` shifts the layout by that amount. For the other layout routines, the extent is \[center - scale, center + scale\] (default: \[-1, 1\]). Warning: Most layout routines have only been tested in 2-dimensions. | | | | --- | --- | | [`arf_layout`](generated/networkx.drawing.layout.arf_layout.html#networkx.drawing.layout.arf_layout "networkx.drawing.layout.arf_layout")
(G\[, pos, scaling, a, etol, dt, ...\]) | Arf layout for networkx | | [`bipartite_layout`](generated/networkx.drawing.layout.bipartite_layout.html#networkx.drawing.layout.bipartite_layout "networkx.drawing.layout.bipartite_layout")
(G, nodes\[, align, scale, ...\]) | Position nodes in two straight lines. | | [`bfs_layout`](generated/networkx.drawing.layout.bfs_layout.html#networkx.drawing.layout.bfs_layout "networkx.drawing.layout.bfs_layout")
(G, start, \*\[, align, scale, center\]) | Position nodes according to breadth-first search algorithm. | | [`circular_layout`](generated/networkx.drawing.layout.circular_layout.html#networkx.drawing.layout.circular_layout "networkx.drawing.layout.circular_layout")
(G\[, scale, center, dim\]) | Position nodes on a circle. | | [`forceatlas2_layout`](generated/networkx.drawing.layout.forceatlas2_layout.html#networkx.drawing.layout.forceatlas2_layout "networkx.drawing.layout.forceatlas2_layout")
(G\[, pos, max\_iter, ...\]) | Position nodes using the ForceAtlas2 force-directed layout algorithm. | | [`kamada_kawai_layout`](generated/networkx.drawing.layout.kamada_kawai_layout.html#networkx.drawing.layout.kamada_kawai_layout "networkx.drawing.layout.kamada_kawai_layout")
(G\[, dist, pos, weight, ...\]) | Position nodes using Kamada-Kawai path-length cost-function. | | [`planar_layout`](generated/networkx.drawing.layout.planar_layout.html#networkx.drawing.layout.planar_layout "networkx.drawing.layout.planar_layout")
(G\[, scale, center, dim\]) | Position nodes without edge intersections. | | [`random_layout`](generated/networkx.drawing.layout.random_layout.html#networkx.drawing.layout.random_layout "networkx.drawing.layout.random_layout")
(G\[, center, dim, seed\]) | Position nodes uniformly at random in the unit square. | | [`rescale_layout`](generated/networkx.drawing.layout.rescale_layout.html#networkx.drawing.layout.rescale_layout "networkx.drawing.layout.rescale_layout")
(pos\[, scale\]) | Returns scaled position array to (-scale, scale) in all axes. | | [`rescale_layout_dict`](generated/networkx.drawing.layout.rescale_layout_dict.html#networkx.drawing.layout.rescale_layout_dict "networkx.drawing.layout.rescale_layout_dict")
(pos\[, scale\]) | Return a dictionary of scaled positions keyed by node | | [`shell_layout`](generated/networkx.drawing.layout.shell_layout.html#networkx.drawing.layout.shell_layout "networkx.drawing.layout.shell_layout")
(G\[, nlist, rotate, scale, ...\]) | Position nodes in concentric circles. | | [`spring_layout`](generated/networkx.drawing.layout.spring_layout.html#networkx.drawing.layout.spring_layout "networkx.drawing.layout.spring_layout")
(G\[, k, pos, fixed, ...\]) | Position nodes using Fruchterman-Reingold force-directed algorithm. | | [`spectral_layout`](generated/networkx.drawing.layout.spectral_layout.html#networkx.drawing.layout.spectral_layout "networkx.drawing.layout.spectral_layout")
(G\[, weight, scale, center, dim\]) | Position nodes using the eigenvectors of the graph Laplacian. | | [`spiral_layout`](generated/networkx.drawing.layout.spiral_layout.html#networkx.drawing.layout.spiral_layout "networkx.drawing.layout.spiral_layout")
(G\[, scale, center, dim, ...\]) | Position nodes in a spiral layout. | | [`multipartite_layout`](generated/networkx.drawing.layout.multipartite_layout.html#networkx.drawing.layout.multipartite_layout "networkx.drawing.layout.multipartite_layout")
(G\[, subset\_key, align, ...\]) | Position nodes in layers of straight lines. | LaTeX Code[#](#module-networkx.drawing.nx_latex "Link to this heading") ------------------------------------------------------------------------ Export NetworkX graphs in LaTeX format using the TikZ library within TeX/LaTeX. Usually, you will want the drawing to appear in a figure environment so you use `to_latex(G, caption="A caption")`. If you want the raw drawing commands without a figure environment use [`to_latex_raw()`](generated/networkx.drawing.nx_latex.to_latex_raw.html#networkx.drawing.nx_latex.to_latex_raw "networkx.drawing.nx_latex.to_latex_raw") . And if you want to write to a file instead of just returning the latex code as a string, use `write_latex(G, "filename.tex", caption="A caption")`. To construct a figure with subfigures for each graph to be shown, provide `to_latex` or `write_latex` a list of graphs, a list of subcaptions, and a number of rows of subfigures inside the figure. To be able to refer to the figures or subfigures in latex using `\\ref`, the keyword `latex_label` is available for figures and `sub_labels` for a list of labels, one for each subfigure. We intend to eventually provide an interface to the TikZ Graph features which include e.g. layout algorithms. Let us know via github what you’d like to see available, or better yet give us some code to do it, or even better make a github pull request to add the feature. ### The TikZ approach[#](#the-tikz-approach "Link to this heading") Drawing options can be stored on the graph as node/edge attributes, or can be provided as dicts keyed by node/edge to a string of the options for that node/edge. Similarly a label can be shown for each node/edge by specifying the labels as graph node/edge attributes or by providing a dict keyed by node/edge to the text to be written for that node/edge. Options for the tikzpicture environment (e.g. “\[scale=2\]”) can be provided via a keyword argument. Similarly default node and edge options can be provided through keywords arguments. The default node options are applied to the single TikZ “path” that draws all nodes (and no edges). The default edge options are applied to a TikZ “scope” which contains a path for each edge. ### Examples[#](#id6 "Link to this heading") \>>> G \= nx.path\_graph(3) \>>> nx.write\_latex(G, "just\_my\_figure.tex", as\_document\=True) \>>> nx.write\_latex(G, "my\_figure.tex", caption\="A path graph", latex\_label\="fig1") \>>> latex\_code \= nx.to\_latex(G) \# a string rather than a file You can change many features of the nodes and edges. \>>> G \= nx.path\_graph(4, create\_using\=nx.DiGraph) \>>> pos \= {n: (n, n) for n in G} \# nodes set on a line \>>> G.nodes\[0\]\["style"\] \= "blue" \>>> G.nodes\[2\]\["style"\] \= "line width=3,draw" \>>> G.nodes\[3\]\["label"\] \= "Stop" \>>> G.edges\[(0, 1)\]\["label"\] \= "1st Step" \>>> G.edges\[(0, 1)\]\["label\_opts"\] \= "near start" \>>> G.edges\[(1, 2)\]\["style"\] \= "line width=3" \>>> G.edges\[(1, 2)\]\["label"\] \= "2nd Step" \>>> G.edges\[(2, 3)\]\["style"\] \= "green" \>>> G.edges\[(2, 3)\]\["label"\] \= "3rd Step" \>>> G.edges\[(2, 3)\]\["label\_opts"\] \= "near end" \>>> nx.write\_latex(G, "latex\_graph.tex", pos\=pos, as\_document\=True) Then compile the LaTeX using something like `pdflatex latex_graph.tex` and view the pdf file created: `latex_graph.pdf`. If you want **subfigures** each containing one graph, you can input a list of graphs. \>>> H1 \= nx.path\_graph(4) \>>> H2 \= nx.complete\_graph(4) \>>> H3 \= nx.path\_graph(8) \>>> H4 \= nx.complete\_graph(8) \>>> graphs \= \[H1, H2, H3, H4\] \>>> caps \= \["Path 4", "Complete graph 4", "Path 8", "Complete graph 8"\] \>>> lbls \= \["fig2a", "fig2b", "fig2c", "fig2d"\] \>>> nx.write\_latex(graphs, "subfigs.tex", n\_rows\=2, sub\_captions\=caps, sub\_labels\=lbls) \>>> latex\_code \= nx.to\_latex(graphs, n\_rows\=2, sub\_captions\=caps, sub\_labels\=lbls) \>>> node\_color \= {0: "red", 1: "orange", 2: "blue", 3: "gray!90"} \>>> edge\_width \= {e: "line width=1.5" for e in H3.edges} \>>> pos \= nx.circular\_layout(H3) \>>> latex\_code \= nx.to\_latex(H3, pos, node\_options\=node\_color, edge\_options\=edge\_width) \>>> print(latex\_code) \\documentclass{report} \\usepackage{tikz} \\usepackage{subcaption} \\begin{document} \\begin{figure} \\begin{tikzpicture} \\draw (1.0, 0.0) node\[red\] (0){0} (0.707, 0.707) node\[orange\] (1){1} (-0.0, 1.0) node\[blue\] (2){2} (-0.707, 0.707) node\[gray!90\] (3){3} (-1.0, -0.0) node (4){4} (-0.707, -0.707) node (5){5} (0.0, -1.0) node (6){6} (0.707, -0.707) node (7){7}; \\begin{scope}\[-\] \\draw\[line width=1.5\] (0) to (1); \\draw\[line width=1.5\] (1) to (2); \\draw\[line width=1.5\] (2) to (3); \\draw\[line width=1.5\] (3) to (4); \\draw\[line width=1.5\] (4) to (5); \\draw\[line width=1.5\] (5) to (6); \\draw\[line width=1.5\] (6) to (7); \\end{scope} \\end{tikzpicture} \\end{figure} \\end{document} #### Notes[#](#notes "Link to this heading") If you want to change the preamble/postamble of the figure/document/subfigure environment, use the keyword arguments: `figure_wrapper`, `document_wrapper`, `subfigure_wrapper`. The default values are stored in private variables e.g. `nx.nx_layout._DOCUMENT_WRAPPER` #### References[#](#references "Link to this heading") TikZ: [https://tikz.dev/](https://tikz.dev/) TikZ options details: [https://tikz.dev/tikz-actions](https://tikz.dev/tikz-actions) | | | | --- | --- | | [`to_latex_raw`](generated/networkx.drawing.nx_latex.to_latex_raw.html#networkx.drawing.nx_latex.to_latex_raw "networkx.drawing.nx_latex.to_latex_raw")
(G\[, pos, tikz\_options, ...\]) | Return a string of the LaTeX/TikZ code to draw `G` | | [`to_latex`](generated/networkx.drawing.nx_latex.to_latex.html#networkx.drawing.nx_latex.to_latex "networkx.drawing.nx_latex.to_latex")
(Gbunch\[, pos, tikz\_options, ...\]) | Return latex code to draw the graph(s) in `Gbunch` | | [`write_latex`](generated/networkx.drawing.nx_latex.write_latex.html#networkx.drawing.nx_latex.write_latex "networkx.drawing.nx_latex.write_latex")
(Gbunch, path, \*\*options) | Write the latex code to draw the graph(s) onto `path`. | On this page --- # Approximations and Heuristics — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Approximations and Heuristics[#](#module-networkx.algorithms.approximation "Link to this heading") =================================================================================================== Approximations of graph properties and Heuristic methods for optimization. The functions in this class are not imported into the top-level `networkx` namespace so the easiest way to use them is with: \>>> from networkx.algorithms import approximation Another option is to import the specific function with `from networkx.algorithms.approximation import function_name`. Connectivity[#](#module-networkx.algorithms.approximation.connectivity "Link to this heading") ----------------------------------------------------------------------------------------------- Fast approximation for node connectivity | | | | --- | --- | | [`all_pairs_node_connectivity`](generated/networkx.algorithms.approximation.connectivity.all_pairs_node_connectivity.html#networkx.algorithms.approximation.connectivity.all_pairs_node_connectivity "networkx.algorithms.approximation.connectivity.all_pairs_node_connectivity")
(G\[, nbunch, cutoff\]) | Compute node connectivity between all pairs of nodes. | | [`local_node_connectivity`](generated/networkx.algorithms.approximation.connectivity.local_node_connectivity.html#networkx.algorithms.approximation.connectivity.local_node_connectivity "networkx.algorithms.approximation.connectivity.local_node_connectivity")
(G, source, target\[, ...\]) | Compute node connectivity between source and target. | | [`node_connectivity`](generated/networkx.algorithms.approximation.connectivity.node_connectivity.html#networkx.algorithms.approximation.connectivity.node_connectivity "networkx.algorithms.approximation.connectivity.node_connectivity")
(G\[, s, t\]) | Returns an approximation for node connectivity for a graph or digraph G. | K-components[#](#module-networkx.algorithms.approximation.kcomponents "Link to this heading") ---------------------------------------------------------------------------------------------- Fast approximation for k-component structure | | | | --- | --- | | [`k_components`](generated/networkx.algorithms.approximation.kcomponents.k_components.html#networkx.algorithms.approximation.kcomponents.k_components "networkx.algorithms.approximation.kcomponents.k_components")
(G\[, min\_density\]) | Returns the approximate k-component structure of a graph G. | Clique[#](#module-networkx.algorithms.approximation.clique "Link to this heading") ----------------------------------------------------------------------------------- Functions for computing large cliques and maximum independent sets. | | | | --- | --- | | [`maximum_independent_set`](generated/networkx.algorithms.approximation.clique.maximum_independent_set.html#networkx.algorithms.approximation.clique.maximum_independent_set "networkx.algorithms.approximation.clique.maximum_independent_set")
(G) | Returns an approximate maximum independent set. | | [`max_clique`](generated/networkx.algorithms.approximation.clique.max_clique.html#networkx.algorithms.approximation.clique.max_clique "networkx.algorithms.approximation.clique.max_clique")
(G) | Find the Maximum Clique | | [`clique_removal`](generated/networkx.algorithms.approximation.clique.clique_removal.html#networkx.algorithms.approximation.clique.clique_removal "networkx.algorithms.approximation.clique.clique_removal")
(G) | Repeatedly remove cliques from the graph. | | [`large_clique_size`](generated/networkx.algorithms.approximation.clique.large_clique_size.html#networkx.algorithms.approximation.clique.large_clique_size "networkx.algorithms.approximation.clique.large_clique_size")
(G) | Find the size of a large clique in a graph. | Clustering[#](#module-networkx.algorithms.approximation.clustering_coefficient "Link to this heading") ------------------------------------------------------------------------------------------------------- | | | | --- | --- | | [`average_clustering`](generated/networkx.algorithms.approximation.clustering_coefficient.average_clustering.html#networkx.algorithms.approximation.clustering_coefficient.average_clustering "networkx.algorithms.approximation.clustering_coefficient.average_clustering")
(G\[, trials, seed\]) | Estimates the average clustering coefficient of G. | Distance Measures[#](#module-networkx.algorithms.approximation.distance_measures "Link to this heading") --------------------------------------------------------------------------------------------------------- Distance measures approximated metrics. | | | | --- | --- | | [`diameter`](generated/networkx.algorithms.approximation.distance_measures.diameter.html#networkx.algorithms.approximation.distance_measures.diameter "networkx.algorithms.approximation.distance_measures.diameter")
(G\[, seed\]) | Returns a lower bound on the diameter of the graph G. | Dominating Set[#](#module-networkx.algorithms.approximation.dominating_set "Link to this heading") --------------------------------------------------------------------------------------------------- Functions for finding node and edge dominating sets. A [dominating set](https://en.wikipedia.org/wiki/Dominating_set) for an undirected graph _G_ with vertex set _V_ and edge set _E_ is a subset _D_ of _V_ such that every vertex not in _D_ is adjacent to at least one member of _D_. An [edge dominating set](https://en.wikipedia.org/wiki/Edge_dominating_set) is a subset _F_ of _E_ such that every edge not in _F_ is incident to an endpoint of at least one edge in _F_. | | | | --- | --- | | [`min_weighted_dominating_set`](generated/networkx.algorithms.approximation.dominating_set.min_weighted_dominating_set.html#networkx.algorithms.approximation.dominating_set.min_weighted_dominating_set "networkx.algorithms.approximation.dominating_set.min_weighted_dominating_set")
(G\[, weight\]) | Returns a dominating set that approximates the minimum weight node dominating set. | | [`min_edge_dominating_set`](generated/networkx.algorithms.approximation.dominating_set.min_edge_dominating_set.html#networkx.algorithms.approximation.dominating_set.min_edge_dominating_set "networkx.algorithms.approximation.dominating_set.min_edge_dominating_set")
(G) | Returns minimum cardinality edge dominating set. | Matching[#](#module-networkx.algorithms.approximation.matching "Link to this heading") --------------------------------------------------------------------------------------- Given a graph G = (V,E), a matching M in G is a set of pairwise non-adjacent edges; that is, no two edges share a common vertex. [Wikipedia: Matching](https://en.wikipedia.org/wiki/Matching_(graph_theory)) | | | | --- | --- | | [`min_maximal_matching`](generated/networkx.algorithms.approximation.matching.min_maximal_matching.html#networkx.algorithms.approximation.matching.min_maximal_matching "networkx.algorithms.approximation.matching.min_maximal_matching")
(G) | Returns the minimum maximal matching of G. | Ramsey[#](#module-networkx.algorithms.approximation.ramsey "Link to this heading") ----------------------------------------------------------------------------------- Ramsey numbers. | | | | --- | --- | | [`ramsey_R2`](generated/networkx.algorithms.approximation.ramsey.ramsey_R2.html#networkx.algorithms.approximation.ramsey.ramsey_R2 "networkx.algorithms.approximation.ramsey.ramsey_R2")
(G) | Compute the largest clique and largest independent set in `G`. | Steiner Tree[#](#module-networkx.algorithms.approximation.steinertree "Link to this heading") ---------------------------------------------------------------------------------------------- | | | | --- | --- | | [`metric_closure`](generated/networkx.algorithms.approximation.steinertree.metric_closure.html#networkx.algorithms.approximation.steinertree.metric_closure "networkx.algorithms.approximation.steinertree.metric_closure")
(G\[, weight\]) | Return the metric closure of a graph. | | [`steiner_tree`](generated/networkx.algorithms.approximation.steinertree.steiner_tree.html#networkx.algorithms.approximation.steinertree.steiner_tree "networkx.algorithms.approximation.steinertree.steiner_tree")
(G, terminal\_nodes\[, weight, method\]) | Return an approximation to the minimum Steiner tree of a graph. | Traveling Salesman[#](#module-networkx.algorithms.approximation.traveling_salesman "Link to this heading") ----------------------------------------------------------------------------------------------------------- ### Travelling Salesman Problem (TSP)[#](#travelling-salesman-problem-tsp "Link to this heading") Implementation of approximate algorithms for solving and approximating the TSP problem. Categories of algorithms which are implemented: * Christofides (provides a 3/2-approximation of TSP) * Greedy * Simulated Annealing (SA) * Threshold Accepting (TA) * Asadpour Asymmetric Traveling Salesman Algorithm The Travelling Salesman Problem tries to find, given the weight (distance) between all points where a salesman has to visit, the route so that: * The total distance (cost) which the salesman travels is minimized. * The salesman returns to the starting point. * Note that for a complete graph, the salesman visits each point once. The function `travelling_salesman_problem` allows for incomplete graphs by finding all-pairs shortest paths, effectively converting the problem to a complete graph problem. It calls one of the approximate methods on that problem and then converts the result back to the original graph using the previously found shortest paths. TSP is an NP-hard problem in combinatorial optimization, important in operations research and theoretical computer science. [http://en.wikipedia.org/wiki/Travelling\_salesman\_problem](http://en.wikipedia.org/wiki/Travelling_salesman_problem) | | | | --- | --- | | [`christofides`](generated/networkx.algorithms.approximation.traveling_salesman.christofides.html#networkx.algorithms.approximation.traveling_salesman.christofides "networkx.algorithms.approximation.traveling_salesman.christofides")
(G\[, weight, tree\]) | Approximate a solution of the traveling salesman problem | | [`traveling_salesman_problem`](generated/networkx.algorithms.approximation.traveling_salesman.traveling_salesman_problem.html#networkx.algorithms.approximation.traveling_salesman.traveling_salesman_problem "networkx.algorithms.approximation.traveling_salesman.traveling_salesman_problem")
(G\[, weight, ...\]) | Find the shortest path in `G` connecting specified nodes | | [`greedy_tsp`](generated/networkx.algorithms.approximation.traveling_salesman.greedy_tsp.html#networkx.algorithms.approximation.traveling_salesman.greedy_tsp "networkx.algorithms.approximation.traveling_salesman.greedy_tsp")
(G\[, weight, source\]) | Return a low cost cycle starting at `source` and its cost. | | [`simulated_annealing_tsp`](generated/networkx.algorithms.approximation.traveling_salesman.simulated_annealing_tsp.html#networkx.algorithms.approximation.traveling_salesman.simulated_annealing_tsp "networkx.algorithms.approximation.traveling_salesman.simulated_annealing_tsp")
(G, init\_cycle\[, ...\]) | Returns an approximate solution to the traveling salesman problem. | | [`threshold_accepting_tsp`](generated/networkx.algorithms.approximation.traveling_salesman.threshold_accepting_tsp.html#networkx.algorithms.approximation.traveling_salesman.threshold_accepting_tsp "networkx.algorithms.approximation.traveling_salesman.threshold_accepting_tsp")
(G, init\_cycle\[, ...\]) | Returns an approximate solution to the traveling salesman problem. | | [`asadpour_atsp`](generated/networkx.algorithms.approximation.traveling_salesman.asadpour_atsp.html#networkx.algorithms.approximation.traveling_salesman.asadpour_atsp "networkx.algorithms.approximation.traveling_salesman.asadpour_atsp")
(G\[, weight, seed, source\]) | Returns an approximate solution to the traveling salesman problem. | Treewidth[#](#module-networkx.algorithms.approximation.treewidth "Link to this heading") ----------------------------------------------------------------------------------------- Functions for computing treewidth decomposition. Treewidth of an undirected graph is a number associated with the graph. It can be defined as the size of the largest vertex set (bag) in a tree decomposition of the graph minus one. [Wikipedia: Treewidth](https://en.wikipedia.org/wiki/Treewidth) The notions of treewidth and tree decomposition have gained their attractiveness partly because many graph and network problems that are intractable (e.g., NP-hard) on arbitrary graphs become efficiently solvable (e.g., with a linear time algorithm) when the treewidth of the input graphs is bounded by a constant [\[1\]](#rfd2b568a4a59-1) [\[2\]](#rfd2b568a4a59-2) . There are two different functions for computing a tree decomposition: [`treewidth_min_degree()`](generated/networkx.algorithms.approximation.treewidth.treewidth_min_degree.html#networkx.algorithms.approximation.treewidth.treewidth_min_degree "networkx.algorithms.approximation.treewidth.treewidth_min_degree") and [`treewidth_min_fill_in()`](generated/networkx.algorithms.approximation.treewidth.treewidth_min_fill_in.html#networkx.algorithms.approximation.treewidth.treewidth_min_fill_in "networkx.algorithms.approximation.treewidth.treewidth_min_fill_in") . \[[1](#id2)\ \] Hans L. Bodlaender and Arie M. C. A. Koster. 2010. “Treewidth computations I.Upper bounds”. Inf. Comput. 208, 3 (March 2010),259-275. [http://dx.doi.org/10.1016/j.ic.2009.03.008](http://dx.doi.org/10.1016/j.ic.2009.03.008) \[[2](#id3)\ \] Hans L. Bodlaender. “Discovering Treewidth”. Institute of Information and Computing Sciences, Utrecht University. Technical Report UU-CS-2005-018. [http://www.cs.uu.nl](http://www.cs.uu.nl) \[3\] K. Wang, Z. Lu, and J. Hicks _Treewidth_. [https://web.archive.org/web/20210507025929/http://web.eecs.utk.edu/~cphill25/cs594\_spring2015\_projects/treewidth.pdf](https://web.archive.org/web/20210507025929/http://web.eecs.utk.edu/~cphill25/cs594_spring2015_projects/treewidth.pdf) | | | | --- | --- | | [`treewidth_min_degree`](generated/networkx.algorithms.approximation.treewidth.treewidth_min_degree.html#networkx.algorithms.approximation.treewidth.treewidth_min_degree "networkx.algorithms.approximation.treewidth.treewidth_min_degree")
(G) | Returns a treewidth decomposition using the Minimum Degree heuristic. | | [`treewidth_min_fill_in`](generated/networkx.algorithms.approximation.treewidth.treewidth_min_fill_in.html#networkx.algorithms.approximation.treewidth.treewidth_min_fill_in "networkx.algorithms.approximation.treewidth.treewidth_min_fill_in")
(G) | Returns a treewidth decomposition using the Minimum Fill-in heuristic. | Vertex Cover[#](#module-networkx.algorithms.approximation.vertex_cover "Link to this heading") ----------------------------------------------------------------------------------------------- Functions for computing an approximate minimum weight vertex cover. A [_vertex cover_](https://en.wikipedia.org/wiki/Vertex_cover) is a subset of nodes such that each edge in the graph is incident to at least one node in the subset. | | | | --- | --- | | [`min_weighted_vertex_cover`](generated/networkx.algorithms.approximation.vertex_cover.min_weighted_vertex_cover.html#networkx.algorithms.approximation.vertex_cover.min_weighted_vertex_cover "networkx.algorithms.approximation.vertex_cover.min_weighted_vertex_cover")
(G\[, weight\]) | Returns an approximate minimum weighted vertex cover. | Max Cut[#](#module-networkx.algorithms.approximation.maxcut "Link to this heading") ------------------------------------------------------------------------------------ | | | | --- | --- | | [`randomized_partitioning`](generated/networkx.algorithms.approximation.maxcut.randomized_partitioning.html#networkx.algorithms.approximation.maxcut.randomized_partitioning "networkx.algorithms.approximation.maxcut.randomized_partitioning")
(G\[, seed, p, weight\]) | Compute a random partitioning of the graph nodes and its cut value. | | [`one_exchange`](generated/networkx.algorithms.approximation.maxcut.one_exchange.html#networkx.algorithms.approximation.maxcut.one_exchange "networkx.algorithms.approximation.maxcut.one_exchange")
(G\[, initial\_cut, seed, weight\]) | Compute a partitioning of the graphs nodes and the corresponding cut value. | On this page --- # Configs — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Configs[#](#configs "Link to this heading") ============================================ Configs provide library-level storage of configuration settings. These settings can be made in code or from environment variables. config[#](#networkx.utils.configs.config "Link to this definition") alias of NetworkXConfig(backend\_priority=BackendPriorities(algos=\[\], generators=\[\]), backends=Config(parallel=ParallelConfig(active=False, backend=’loky’, n\_jobs=None, verbose=0, temp\_folder=None, max\_nbytes=’1M’, mmap\_mode=’r’, prefer=None, require=None, inner\_max\_num\_threads=None, backend\_params={}), cugraph=Config(use\_compat\_graphs=True), graphblas=Config()), cache\_converted\_graphs=True, fallback\_to\_nx=False, warnings\_to\_ignore=set()) _class_ NetworkXConfig(_\*\*kwargs_)[\[source\]](../_modules/networkx/utils/configs.html#NetworkXConfig) [#](#networkx.utils.configs.NetworkXConfig "Link to this definition") Configuration for NetworkX that controls behaviors such as how to use backends. Attribute and bracket notation are supported for getting and setting configurations: \>>> nx.config.backend\_priority \== nx.config\["backend\_priority"\] True Parameters: **backend\_priority**list of backend names or dict or BackendPriorities Enable automatic conversion of graphs to backend graphs for functions implemented by the backend. Priority is given to backends listed earlier. This is a nested configuration with keys `algos`, `generators`, and, optionally, function names. Setting this value to a list of backend names will set `nx.config.backend_priority.algos`. For more information, see `help(nx.config.backend_priority)`. Default is empty list. **backends**Config mapping of backend names to backend Config The keys of the Config mapping are names of all installed NetworkX backends, and the values are their configurations as Config mappings. **cache\_converted\_graphs**bool If True, then save converted graphs to the cache of the input graph. Graph conversion may occur when automatically using a backend from `backend_priority` or when using the `backend=` keyword argument to a function call. Caching can improve performance by avoiding repeated conversions, but it uses more memory. Care should be taken to not manually mutate a graph that has cached graphs; for example, `G[u][v][k] = val` changes the graph, but does not clear the cache. Using methods such as `G.add_edge(u, v, weight=val)` will clear the cache to keep it consistent. `G.__networkx_cache__.clear()` manually clears the cache. Default is True. **fallback\_to\_nx**bool If True, then “fall back” and run with the default “networkx” implementation for dispatchable functions not implemented by backends of input graphs. When a backend graph is passed to a dispatchable function, the default behavior is to use the implementation from that backend if possible and raise if not. Enabling `fallback_to_nx` makes the networkx implementation the fallback to use instead of raising, and will convert the backend graph to a networkx-compatible graph. Default is False. **warnings\_to\_ignore**set of strings Control which warnings from NetworkX are not emitted. Valid elements: * `"cache"`: when a cached value is used from `G.__networkx_cache__`. Notes Environment variables may be used to control some default configurations: * `NETWORKX_BACKEND_PRIORITY`: set `backend_priority.algos` from comma-separated names. * `NETWORKX_CACHE_CONVERTED_GRAPHS`: set `cache_converted_graphs` to True if nonempty. * `NETWORKX_FALLBACK_TO_NX`: set `fallback_to_nx` to True if nonempty. * `NETWORKX_WARNINGS_TO_IGNORE`: set `warnings_to_ignore` from comma-separated names. and can be used for finer control of `backend_priority` such as: * `NETWORKX_BACKEND_PRIORITY_ALGOS`: same as `NETWORKX_BACKEND_PRIORITY` to set `backend_priority.algos`. This is a global configuration. Use with caution when using from multiple threads. _class_ Config(_\*\*kwargs_)[\[source\]](../_modules/networkx/utils/configs.html#Config) [#](#networkx.utils.configs.Config "Link to this definition") The base class for NetworkX configuration. There are two ways to use this to create configurations. The recommended way is to subclass `Config` with docs and annotations. \>>> class MyConfig(Config): ... '''Breakfast!''' ... ... eggs: int ... spam: int ... ... def \_on\_setattr(self, key, value): ... assert isinstance(value, int) and value \>= 0 ... return value \>>> cfg \= MyConfig(eggs\=1, spam\=5) Another way is to simply pass the initial configuration as keyword arguments to the `Config` instance: \>>> cfg1 \= Config(eggs\=1, spam\=5) \>>> cfg1 Config(eggs=1, spam=5) Once defined, config items may be modified, but can’t be added or deleted by default. `Config` is a `Mapping`, and can get and set configs via attributes or brackets: \>>> cfg.eggs \= 2 \>>> cfg.eggs 2 \>>> cfg\["spam"\] \= 42 \>>> cfg\["spam"\] 42 For convenience, it can also set configs within a context with the “with” statement: \>>> with cfg(spam\=3): ... print("spam (in context):", cfg.spam) spam (in context): 3 \>>> print("spam (after context):", cfg.spam) spam (after context): 42 Subclasses may also define `_on_setattr` (as done in the example above) to ensure the value being assigned is valid: \>>> cfg.spam \= \-1 Traceback (most recent call last): ... AssertionError If a more flexible configuration object is needed that allows adding and deleting configurations, then pass `strict=False` when defining the subclass: \>>> class FlexibleConfig(Config, strict\=False): ... default\_greeting: str \= "Hello" \>>> flexcfg \= FlexibleConfig() \>>> flexcfg.name \= "Mr. Anderson" \>>> flexcfg FlexibleConfig(default\_greeting='Hello', name='Mr. Anderson') On this page --- # Assortativity — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Assortativity[#](#module-networkx.algorithms.assortativity "Link to this heading") =================================================================================== Assortativity[#](#networkx-algorithms-assortativity-correlation "Link to this heading") ---------------------------------------------------------------------------------------- | | | | --- | --- | | [`degree_assortativity_coefficient`](generated/networkx.algorithms.assortativity.degree_assortativity_coefficient.html#networkx.algorithms.assortativity.degree_assortativity_coefficient "networkx.algorithms.assortativity.degree_assortativity_coefficient")
(G\[, x, y, ...\]) | Compute degree assortativity of graph. | | [`attribute_assortativity_coefficient`](generated/networkx.algorithms.assortativity.attribute_assortativity_coefficient.html#networkx.algorithms.assortativity.attribute_assortativity_coefficient "networkx.algorithms.assortativity.attribute_assortativity_coefficient")
(G, attribute) | Compute assortativity for node attributes. | | [`numeric_assortativity_coefficient`](generated/networkx.algorithms.assortativity.numeric_assortativity_coefficient.html#networkx.algorithms.assortativity.numeric_assortativity_coefficient "networkx.algorithms.assortativity.numeric_assortativity_coefficient")
(G, attribute) | Compute assortativity for numerical node attributes. | | [`degree_pearson_correlation_coefficient`](generated/networkx.algorithms.assortativity.degree_pearson_correlation_coefficient.html#networkx.algorithms.assortativity.degree_pearson_correlation_coefficient "networkx.algorithms.assortativity.degree_pearson_correlation_coefficient")
(G\[, ...\]) | Compute degree assortativity of graph. | Average neighbor degree[#](#average-neighbor-degree "Link to this heading") ---------------------------------------------------------------------------- | | | | --- | --- | | [`average_neighbor_degree`](generated/networkx.algorithms.assortativity.average_neighbor_degree.html#networkx.algorithms.assortativity.average_neighbor_degree "networkx.algorithms.assortativity.average_neighbor_degree")
(G\[, source, target, ...\]) | Returns the average degree of the neighborhood of each node. | Average degree connectivity[#](#average-degree-connectivity "Link to this heading") ------------------------------------------------------------------------------------ | | | | --- | --- | | [`average_degree_connectivity`](generated/networkx.algorithms.assortativity.average_degree_connectivity.html#networkx.algorithms.assortativity.average_degree_connectivity "networkx.algorithms.assortativity.average_degree_connectivity")
(G\[, source, ...\]) | Compute the average degree connectivity of graph. | Mixing[#](#mixing "Link to this heading") ------------------------------------------ | | | | --- | --- | | [`attribute_mixing_matrix`](generated/networkx.algorithms.assortativity.attribute_mixing_matrix.html#networkx.algorithms.assortativity.attribute_mixing_matrix "networkx.algorithms.assortativity.attribute_mixing_matrix")
(G, attribute\[, ...\]) | Returns mixing matrix for attribute. | | [`degree_mixing_matrix`](generated/networkx.algorithms.assortativity.degree_mixing_matrix.html#networkx.algorithms.assortativity.degree_mixing_matrix "networkx.algorithms.assortativity.degree_mixing_matrix")
(G\[, x, y, weight, ...\]) | Returns mixing matrix for attribute. | | [`attribute_mixing_dict`](generated/networkx.algorithms.assortativity.attribute_mixing_dict.html#networkx.algorithms.assortativity.attribute_mixing_dict "networkx.algorithms.assortativity.attribute_mixing_dict")
(G, attribute\[, nodes, ...\]) | Returns dictionary representation of mixing matrix for attribute. | | [`degree_mixing_dict`](generated/networkx.algorithms.assortativity.degree_mixing_dict.html#networkx.algorithms.assortativity.degree_mixing_dict "networkx.algorithms.assortativity.degree_mixing_dict")
(G\[, x, y, weight, nodes, ...\]) | Returns dictionary representation of mixing matrix for degree. | | [`mixing_dict`](generated/networkx.algorithms.assortativity.mixing_dict.html#networkx.algorithms.assortativity.mixing_dict "networkx.algorithms.assortativity.mixing_dict")
(xy\[, normalized\]) | Returns a dictionary representation of mixing matrix. | Pairs[#](#pairs "Link to this heading") ---------------------------------------- | | | | --- | --- | | [`node_attribute_xy`](generated/networkx.algorithms.assortativity.node_attribute_xy.html#networkx.algorithms.assortativity.node_attribute_xy "networkx.algorithms.assortativity.node_attribute_xy")
(G, attribute\[, nodes\]) | Yields 2-tuples of node attribute values for all edges in `G`. | | [`node_degree_xy`](generated/networkx.algorithms.assortativity.node_degree_xy.html#networkx.algorithms.assortativity.node_degree_xy "networkx.algorithms.assortativity.node_degree_xy")
(G\[, x, y, weight, nodes\]) | Yields 2-tuples of `(degree, degree)` values for edges in `G`. | On this page --- # Asteroidal — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Asteroidal[#](#module-networkx.algorithms.asteroidal "Link to this heading") ============================================================================= Algorithms for asteroidal triples and asteroidal numbers in graphs. An asteroidal triple in a graph G is a set of three non-adjacent vertices u, v and w such that there exist a path between any two of them that avoids closed neighborhood of the third. More formally, v\_j, v\_k belongs to the same connected component of G - N\[v\_i\], where N\[v\_i\] denotes the closed neighborhood of v\_i. A graph which does not contain any asteroidal triples is called an AT-free graph. The class of AT-free graphs is a graph class for which many NP-complete problems are solvable in polynomial time. Amongst them, independent set and coloring. | | | | --- | --- | | [`is_at_free`](generated/networkx.algorithms.asteroidal.is_at_free.html#networkx.algorithms.asteroidal.is_at_free "networkx.algorithms.asteroidal.is_at_free")
(G) | Check if a graph is AT-free. | | [`find_asteroidal_triple`](generated/networkx.algorithms.asteroidal.find_asteroidal_triple.html#networkx.algorithms.asteroidal.find_asteroidal_triple "networkx.algorithms.asteroidal.find_asteroidal_triple")
(G) | Find an asteroidal triple in the given graph. | --- # Boundary — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Boundary[#](#module-networkx.algorithms.boundary "Link to this heading") ========================================================================= Routines to find the boundary of a set of nodes. An edge boundary is a set of edges, each of which has exactly one endpoint in a given set of nodes (or, in the case of directed graphs, the set of edges whose source node is in the set). A node boundary of a set _S_ of nodes is the set of (out-)neighbors of nodes in _S_ that are outside _S_. | | | | --- | --- | | [`edge_boundary`](generated/networkx.algorithms.boundary.edge_boundary.html#networkx.algorithms.boundary.edge_boundary "networkx.algorithms.boundary.edge_boundary")
(G, nbunch1\[, nbunch2, data, ...\]) | Returns the edge boundary of `nbunch1`. | | [`node_boundary`](generated/networkx.algorithms.boundary.node_boundary.html#networkx.algorithms.boundary.node_boundary "networkx.algorithms.boundary.node_boundary")
(G, nbunch1\[, nbunch2\]) | Returns the node boundary of `nbunch1`. | --- # Broadcasting — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Broadcasting[#](#module-networkx.algorithms.broadcasting "Link to this heading") ================================================================================= Routines to calculate the broadcast time of certain graphs. Broadcasting is an information dissemination problem in which a node in a graph, called the originator, must distribute a message to all other nodes by placing a series of calls along the edges of the graph. Once informed, other nodes aid the originator in distributing the message. The broadcasting must be completed as quickly as possible subject to the following constraints: - Each call requires one unit of time. - A node can only participate in one call per unit of time. - Each call only involves two adjacent nodes: a sender and a receiver. | | | | --- | --- | | [`tree_broadcast_center`](generated/networkx.algorithms.broadcasting.tree_broadcast_center.html#networkx.algorithms.broadcasting.tree_broadcast_center "networkx.algorithms.broadcasting.tree_broadcast_center")
(G) | Return the Broadcast Center of the tree `G`. | | [`tree_broadcast_time`](generated/networkx.algorithms.broadcasting.tree_broadcast_time.html#networkx.algorithms.broadcasting.tree_broadcast_time "networkx.algorithms.broadcasting.tree_broadcast_time")
(G\[, node\]) | Return the Broadcast Time of the tree `G`. | --- # Bipartite — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Bipartite[#](#module-networkx.algorithms.bipartite "Link to this heading") =========================================================================== This module provides functions and operations for bipartite graphs. Bipartite graphs `B = (U, V, E)` have two node sets `U,V` and edges in `E` that only connect nodes from opposite sets. It is common in the literature to use an spatial analogy referring to the two node sets as top and bottom nodes. The bipartite algorithms are not imported into the networkx namespace at the top level so the easiest way to use them is with: \>>> from networkx.algorithms import bipartite NetworkX does not have a custom bipartite graph class but the Graph() or DiGraph() classes can be used to represent bipartite graphs. However, you have to keep track of which set each node belongs to, and make sure that there is no edge between nodes of the same set. The convention used in NetworkX is to use a node attribute named `bipartite` with values 0 or 1 to identify the sets each node belongs to. This convention is not enforced in the source code of bipartite functions, it’s only a recommendation. For example: \>>> B \= nx.Graph() \>>> \# Add nodes with the node attribute "bipartite" \>>> B.add\_nodes\_from(\[1, 2, 3, 4\], bipartite\=0) \>>> B.add\_nodes\_from(\["a", "b", "c"\], bipartite\=1) \>>> \# Add edges only between nodes of opposite node sets \>>> B.add\_edges\_from(\[(1, "a"), (1, "b"), (2, "b"), (2, "c"), (3, "c"), (4, "a")\]) Many algorithms of the bipartite module of NetworkX require, as an argument, a container with all the nodes that belong to one set, in addition to the bipartite graph `B`. The functions in the bipartite package do not check that the node set is actually correct nor that the input graph is actually bipartite. If `B` is connected, you can find the two node sets using a two-coloring algorithm: \>>> nx.is\_connected(B) True \>>> bottom\_nodes, top\_nodes \= bipartite.sets(B) However, if the input graph is not connected, there are more than one possible colorations. This is the reason why we require the user to pass a container with all nodes of one bipartite node set as an argument to most bipartite functions. In the face of ambiguity, we refuse the temptation to guess and raise an [`AmbiguousSolution`](../exceptions.html#networkx.AmbiguousSolution "networkx.AmbiguousSolution") Exception if the input graph for [`bipartite.sets`](generated/networkx.algorithms.bipartite.basic.sets.html#networkx.algorithms.bipartite.basic.sets "networkx.algorithms.bipartite.basic.sets") is disconnected. Using the `bipartite` node attribute, you can easily get the two node sets: \>>> top\_nodes \= {n for n, d in B.nodes(data\=True) if d\["bipartite"\] \== 0} \>>> bottom\_nodes \= set(B) \- top\_nodes So you can easily use the bipartite algorithms that require, as an argument, a container with all nodes that belong to one node set: \>>> print(round(bipartite.density(B, bottom\_nodes), 2)) 0.5 \>>> G \= bipartite.projected\_graph(B, top\_nodes) All bipartite graph generators in NetworkX build bipartite graphs with the `bipartite` node attribute. Thus, you can use the same approach: \>>> RB \= bipartite.random\_graph(5, 7, 0.2) \>>> RB\_top \= {n for n, d in RB.nodes(data\=True) if d\["bipartite"\] \== 0} \>>> RB\_bottom \= set(RB) \- RB\_top \>>> list(RB\_top) \[0, 1, 2, 3, 4\] \>>> list(RB\_bottom) \[5, 6, 7, 8, 9, 10, 11\] For other bipartite graph generators see [`Generators`](#module-networkx.algorithms.bipartite.generators "networkx.algorithms.bipartite.generators") . Basic functions[#](#module-networkx.algorithms.bipartite.basic "Link to this heading") --------------------------------------------------------------------------------------- | | | | --- | --- | | [`is_bipartite`](generated/networkx.algorithms.bipartite.basic.is_bipartite.html#networkx.algorithms.bipartite.basic.is_bipartite "networkx.algorithms.bipartite.basic.is_bipartite")
(G) | Returns True if graph G is bipartite, False if not. | | [`is_bipartite_node_set`](generated/networkx.algorithms.bipartite.basic.is_bipartite_node_set.html#networkx.algorithms.bipartite.basic.is_bipartite_node_set "networkx.algorithms.bipartite.basic.is_bipartite_node_set")
(G, nodes) | Returns True if nodes and G/nodes are a bipartition of G. | | [`sets`](generated/networkx.algorithms.bipartite.basic.sets.html#networkx.algorithms.bipartite.basic.sets "networkx.algorithms.bipartite.basic.sets")
(G\[, top\_nodes\]) | Returns bipartite node sets of graph G. | | [`color`](generated/networkx.algorithms.bipartite.basic.color.html#networkx.algorithms.bipartite.basic.color "networkx.algorithms.bipartite.basic.color")
(G) | Returns a two-coloring of the graph. | | [`density`](generated/networkx.algorithms.bipartite.basic.density.html#networkx.algorithms.bipartite.basic.density "networkx.algorithms.bipartite.basic.density")
(B, nodes) | Returns density of bipartite graph B. | | [`degrees`](generated/networkx.algorithms.bipartite.basic.degrees.html#networkx.algorithms.bipartite.basic.degrees "networkx.algorithms.bipartite.basic.degrees")
(B, nodes\[, weight\]) | Returns the degrees of the two node sets in the bipartite graph B. | Edgelist[#](#module-networkx.algorithms.bipartite.edgelist "Link to this heading") ----------------------------------------------------------------------------------- Read and write NetworkX graphs as bipartite edge lists. ### Format[#](#format "Link to this heading") You can read or write three formats of edge lists with these functions. Node pairs with no data: 1 2 Python dictionary as data: 1 2 {'weight':7, 'color':'green'} Arbitrary data: 1 2 7 green For each edge (u, v) the node u is assigned to part 0 and the node v to part 1. | | | | --- | --- | | [`generate_edgelist`](generated/networkx.algorithms.bipartite.edgelist.generate_edgelist.html#networkx.algorithms.bipartite.edgelist.generate_edgelist "networkx.algorithms.bipartite.edgelist.generate_edgelist")
(G\[, delimiter, data\]) | Generate a single line of the bipartite graph G in edge list format. | | [`write_edgelist`](generated/networkx.algorithms.bipartite.edgelist.write_edgelist.html#networkx.algorithms.bipartite.edgelist.write_edgelist "networkx.algorithms.bipartite.edgelist.write_edgelist")
(G, path\[, comments, ...\]) | Write a bipartite graph as a list of edges. | | [`parse_edgelist`](generated/networkx.algorithms.bipartite.edgelist.parse_edgelist.html#networkx.algorithms.bipartite.edgelist.parse_edgelist "networkx.algorithms.bipartite.edgelist.parse_edgelist")
(lines\[, comments, delimiter, ...\]) | Parse lines of an edge list representation of a bipartite graph. | | [`read_edgelist`](generated/networkx.algorithms.bipartite.edgelist.read_edgelist.html#networkx.algorithms.bipartite.edgelist.read_edgelist "networkx.algorithms.bipartite.edgelist.read_edgelist")
(path\[, comments, delimiter, ...\]) | Read a bipartite graph from a list of edges. | Matching[#](#module-networkx.algorithms.bipartite.matching "Link to this heading") ----------------------------------------------------------------------------------- Provides functions for computing maximum cardinality matchings and minimum weight full matchings in a bipartite graph. If you don’t care about the particular implementation of the maximum matching algorithm, simply use the [`maximum_matching()`](generated/networkx.algorithms.bipartite.matching.maximum_matching.html#networkx.algorithms.bipartite.matching.maximum_matching "networkx.algorithms.bipartite.matching.maximum_matching") . If you do care, you can import one of the named maximum matching algorithms directly. For example, to find a maximum matching in the complete bipartite graph with two vertices on the left and three vertices on the right: \>>> G \= nx.complete\_bipartite\_graph(2, 3) \>>> left, right \= nx.bipartite.sets(G) \>>> list(left) \[0, 1\] \>>> list(right) \[2, 3, 4\] \>>> nx.bipartite.maximum\_matching(G) {0: 2, 1: 3, 2: 0, 3: 1} The dictionary returned by [`maximum_matching()`](generated/networkx.algorithms.bipartite.matching.maximum_matching.html#networkx.algorithms.bipartite.matching.maximum_matching "networkx.algorithms.bipartite.matching.maximum_matching") includes a mapping for vertices in both the left and right vertex sets. Similarly, [`minimum_weight_full_matching()`](generated/networkx.algorithms.bipartite.matching.minimum_weight_full_matching.html#networkx.algorithms.bipartite.matching.minimum_weight_full_matching "networkx.algorithms.bipartite.matching.minimum_weight_full_matching") produces, for a complete weighted bipartite graph, a matching whose cardinality is the cardinality of the smaller of the two partitions, and for which the sum of the weights of the edges included in the matching is minimal. | | | | --- | --- | | [`eppstein_matching`](generated/networkx.algorithms.bipartite.matching.eppstein_matching.html#networkx.algorithms.bipartite.matching.eppstein_matching "networkx.algorithms.bipartite.matching.eppstein_matching")
(G\[, top\_nodes\]) | Returns the maximum cardinality matching of the bipartite graph `G`. | | [`hopcroft_karp_matching`](generated/networkx.algorithms.bipartite.matching.hopcroft_karp_matching.html#networkx.algorithms.bipartite.matching.hopcroft_karp_matching "networkx.algorithms.bipartite.matching.hopcroft_karp_matching")
(G\[, top\_nodes\]) | Returns the maximum cardinality matching of the bipartite graph `G`. | | [`to_vertex_cover`](generated/networkx.algorithms.bipartite.matching.to_vertex_cover.html#networkx.algorithms.bipartite.matching.to_vertex_cover "networkx.algorithms.bipartite.matching.to_vertex_cover")
(G, matching\[, top\_nodes\]) | Returns the minimum vertex cover corresponding to the given maximum matching of the bipartite graph `G`. | | [`maximum_matching`](generated/networkx.algorithms.bipartite.matching.maximum_matching.html#networkx.algorithms.bipartite.matching.maximum_matching "networkx.algorithms.bipartite.matching.maximum_matching")
(G\[, top\_nodes\]) | Returns the maximum cardinality matching in the given bipartite graph. | | [`minimum_weight_full_matching`](generated/networkx.algorithms.bipartite.matching.minimum_weight_full_matching.html#networkx.algorithms.bipartite.matching.minimum_weight_full_matching "networkx.algorithms.bipartite.matching.minimum_weight_full_matching")
(G\[, top\_nodes, ...\]) | Returns a minimum weight full matching of the bipartite graph `G`. | Matrix[#](#module-networkx.algorithms.bipartite.matrix "Link to this heading") ------------------------------------------------------------------------------- | | | | --- | --- | | [`biadjacency_matrix`](generated/networkx.algorithms.bipartite.matrix.biadjacency_matrix.html#networkx.algorithms.bipartite.matrix.biadjacency_matrix "networkx.algorithms.bipartite.matrix.biadjacency_matrix")
(G, row\_order\[, ...\]) | Returns the biadjacency matrix of the bipartite graph G. | | [`from_biadjacency_matrix`](generated/networkx.algorithms.bipartite.matrix.from_biadjacency_matrix.html#networkx.algorithms.bipartite.matrix.from_biadjacency_matrix "networkx.algorithms.bipartite.matrix.from_biadjacency_matrix")
(A\[, create\_using, ...\]) | Creates a new bipartite graph from a biadjacency matrix given as a SciPy sparse array. | Projections[#](#module-networkx.algorithms.bipartite.projection "Link to this heading") ---------------------------------------------------------------------------------------- One-mode (unipartite) projections of bipartite graphs. | | | | --- | --- | | [`projected_graph`](generated/networkx.algorithms.bipartite.projection.projected_graph.html#networkx.algorithms.bipartite.projection.projected_graph "networkx.algorithms.bipartite.projection.projected_graph")
(B, nodes\[, multigraph\]) | Returns the projection of B onto one of its node sets. | | [`weighted_projected_graph`](generated/networkx.algorithms.bipartite.projection.weighted_projected_graph.html#networkx.algorithms.bipartite.projection.weighted_projected_graph "networkx.algorithms.bipartite.projection.weighted_projected_graph")
(B, nodes\[, ratio\]) | Returns a weighted projection of B onto one of its node sets. | | [`collaboration_weighted_projected_graph`](generated/networkx.algorithms.bipartite.projection.collaboration_weighted_projected_graph.html#networkx.algorithms.bipartite.projection.collaboration_weighted_projected_graph "networkx.algorithms.bipartite.projection.collaboration_weighted_projected_graph")
(B, nodes) | Newman's weighted projection of B onto one of its node sets. | | [`overlap_weighted_projected_graph`](generated/networkx.algorithms.bipartite.projection.overlap_weighted_projected_graph.html#networkx.algorithms.bipartite.projection.overlap_weighted_projected_graph "networkx.algorithms.bipartite.projection.overlap_weighted_projected_graph")
(B, nodes\[, ...\]) | Overlap weighted projection of B onto one of its node sets. | | [`generic_weighted_projected_graph`](generated/networkx.algorithms.bipartite.projection.generic_weighted_projected_graph.html#networkx.algorithms.bipartite.projection.generic_weighted_projected_graph "networkx.algorithms.bipartite.projection.generic_weighted_projected_graph")
(B, nodes\[, ...\]) | Weighted projection of B with a user-specified weight function. | Spectral[#](#module-networkx.algorithms.bipartite.spectral "Link to this heading") ----------------------------------------------------------------------------------- Spectral bipartivity measure. | | | | --- | --- | | [`spectral_bipartivity`](generated/networkx.algorithms.bipartite.spectral.spectral_bipartivity.html#networkx.algorithms.bipartite.spectral.spectral_bipartivity "networkx.algorithms.bipartite.spectral.spectral_bipartivity")
(G\[, nodes, weight\]) | Returns the spectral bipartivity. | Clustering[#](#module-networkx.algorithms.bipartite.cluster "Link to this heading") ------------------------------------------------------------------------------------ Functions for computing clustering of pairs | | | | --- | --- | | [`clustering`](generated/networkx.algorithms.bipartite.cluster.clustering.html#networkx.algorithms.bipartite.cluster.clustering "networkx.algorithms.bipartite.cluster.clustering")
(G\[, nodes, mode\]) | Compute a bipartite clustering coefficient for nodes. | | [`average_clustering`](generated/networkx.algorithms.bipartite.cluster.average_clustering.html#networkx.algorithms.bipartite.cluster.average_clustering "networkx.algorithms.bipartite.cluster.average_clustering")
(G\[, nodes, mode\]) | Compute the average bipartite clustering coefficient. | | [`latapy_clustering`](generated/networkx.algorithms.bipartite.cluster.latapy_clustering.html#networkx.algorithms.bipartite.cluster.latapy_clustering "networkx.algorithms.bipartite.cluster.latapy_clustering")
(G\[, nodes, mode\]) | Compute a bipartite clustering coefficient for nodes. | | [`robins_alexander_clustering`](generated/networkx.algorithms.bipartite.cluster.robins_alexander_clustering.html#networkx.algorithms.bipartite.cluster.robins_alexander_clustering "networkx.algorithms.bipartite.cluster.robins_alexander_clustering")
(G) | Compute the bipartite clustering of G. | Redundancy[#](#module-networkx.algorithms.bipartite.redundancy "Link to this heading") --------------------------------------------------------------------------------------- Node redundancy for bipartite graphs. | | | | --- | --- | | [`node_redundancy`](generated/networkx.algorithms.bipartite.redundancy.node_redundancy.html#networkx.algorithms.bipartite.redundancy.node_redundancy "networkx.algorithms.bipartite.redundancy.node_redundancy")
(G\[, nodes\]) | Computes the node redundancy coefficients for the nodes in the bipartite graph `G`. | Centrality[#](#module-networkx.algorithms.bipartite.centrality "Link to this heading") --------------------------------------------------------------------------------------- | | | | --- | --- | | [`closeness_centrality`](generated/networkx.algorithms.bipartite.centrality.closeness_centrality.html#networkx.algorithms.bipartite.centrality.closeness_centrality "networkx.algorithms.bipartite.centrality.closeness_centrality")
(G, nodes\[, normalized\]) | Compute the closeness centrality for nodes in a bipartite network. | | [`degree_centrality`](generated/networkx.algorithms.bipartite.centrality.degree_centrality.html#networkx.algorithms.bipartite.centrality.degree_centrality "networkx.algorithms.bipartite.centrality.degree_centrality")
(G, nodes) | Compute the degree centrality for nodes in a bipartite network. | | [`betweenness_centrality`](generated/networkx.algorithms.bipartite.centrality.betweenness_centrality.html#networkx.algorithms.bipartite.centrality.betweenness_centrality "networkx.algorithms.bipartite.centrality.betweenness_centrality")
(G, nodes) | Compute betweenness centrality for nodes in a bipartite network. | Generators[#](#module-networkx.algorithms.bipartite.generators "Link to this heading") --------------------------------------------------------------------------------------- Generators and functions for bipartite graphs. | | | | --- | --- | | [`complete_bipartite_graph`](generated/networkx.algorithms.bipartite.generators.complete_bipartite_graph.html#networkx.algorithms.bipartite.generators.complete_bipartite_graph "networkx.algorithms.bipartite.generators.complete_bipartite_graph")
(n1, n2\[, create\_using\]) | Returns the complete bipartite graph `K_{n_1,n_2}`. | | [`configuration_model`](generated/networkx.algorithms.bipartite.generators.configuration_model.html#networkx.algorithms.bipartite.generators.configuration_model "networkx.algorithms.bipartite.generators.configuration_model")
(aseq, bseq\[, ...\]) | Returns a random bipartite graph from two given degree sequences. | | [`havel_hakimi_graph`](generated/networkx.algorithms.bipartite.generators.havel_hakimi_graph.html#networkx.algorithms.bipartite.generators.havel_hakimi_graph "networkx.algorithms.bipartite.generators.havel_hakimi_graph")
(aseq, bseq\[, create\_using\]) | Returns a bipartite graph from two given degree sequences using a Havel-Hakimi style construction. | | [`reverse_havel_hakimi_graph`](generated/networkx.algorithms.bipartite.generators.reverse_havel_hakimi_graph.html#networkx.algorithms.bipartite.generators.reverse_havel_hakimi_graph "networkx.algorithms.bipartite.generators.reverse_havel_hakimi_graph")
(aseq, bseq\[, ...\]) | Returns a bipartite graph from two given degree sequences using a Havel-Hakimi style construction. | | [`alternating_havel_hakimi_graph`](generated/networkx.algorithms.bipartite.generators.alternating_havel_hakimi_graph.html#networkx.algorithms.bipartite.generators.alternating_havel_hakimi_graph "networkx.algorithms.bipartite.generators.alternating_havel_hakimi_graph")
(aseq, bseq\[, ...\]) | Returns a bipartite graph from two given degree sequences using an alternating Havel-Hakimi style construction. | | [`preferential_attachment_graph`](generated/networkx.algorithms.bipartite.generators.preferential_attachment_graph.html#networkx.algorithms.bipartite.generators.preferential_attachment_graph "networkx.algorithms.bipartite.generators.preferential_attachment_graph")
(aseq, p\[, ...\]) | Create a bipartite graph with a preferential attachment model from a given single degree sequence. | | [`random_graph`](generated/networkx.algorithms.bipartite.generators.random_graph.html#networkx.algorithms.bipartite.generators.random_graph "networkx.algorithms.bipartite.generators.random_graph")
(n, m, p\[, seed, directed\]) | Returns a bipartite random graph. | | [`gnmk_random_graph`](generated/networkx.algorithms.bipartite.generators.gnmk_random_graph.html#networkx.algorithms.bipartite.generators.gnmk_random_graph "networkx.algorithms.bipartite.generators.gnmk_random_graph")
(n, m, k\[, seed, directed\]) | Returns a random bipartite graph G\_{n,m,k}. | Covering[#](#module-networkx.algorithms.bipartite.covering "Link to this heading") ----------------------------------------------------------------------------------- Functions related to graph covers. | | | | --- | --- | | [`min_edge_cover`](generated/networkx.algorithms.bipartite.covering.min_edge_cover.html#networkx.algorithms.bipartite.covering.min_edge_cover "networkx.algorithms.bipartite.covering.min_edge_cover")
(G\[, matching\_algorithm\]) | Returns a set of edges which constitutes the minimum edge cover of the graph. | Extendability[#](#module-networkx.algorithms.bipartite.extendability "Link to this heading") --------------------------------------------------------------------------------------------- Provides a function for computing the extendability of a graph which is undirected, simple, connected and bipartite and contains at least one perfect matching. | | | | --- | --- | | [`maximal_extendability`](generated/networkx.algorithms.bipartite.extendability.maximal_extendability.html#networkx.algorithms.bipartite.extendability.maximal_extendability "networkx.algorithms.bipartite.extendability.maximal_extendability")
(G) | Computes the extendability of a graph. | On this page --- # Bridges — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Bridges[#](#module-networkx.algorithms.bridges "Link to this heading") ======================================================================= Bridge-finding algorithms. | | | | --- | --- | | [`bridges`](generated/networkx.algorithms.bridges.bridges.html#networkx.algorithms.bridges.bridges "networkx.algorithms.bridges.bridges")
(G\[, root\]) | Generate all bridges in a graph. | | [`has_bridges`](generated/networkx.algorithms.bridges.has_bridges.html#networkx.algorithms.bridges.has_bridges "networkx.algorithms.bridges.has_bridges")
(G\[, root\]) | Decide whether a graph has any bridges. | | [`local_bridges`](generated/networkx.algorithms.bridges.local_bridges.html#networkx.algorithms.bridges.local_bridges "networkx.algorithms.bridges.local_bridges")
(G\[, with\_span, weight\]) | Iterate over local bridges of `G` optionally computing the span | --- # Chains — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Chains[#](#module-networkx.algorithms.chains "Link to this heading") ===================================================================== Functions for finding chains in a graph. | | | | --- | --- | | [`chain_decomposition`](generated/networkx.algorithms.chains.chain_decomposition.html#networkx.algorithms.chains.chain_decomposition "networkx.algorithms.chains.chain_decomposition")
(G\[, root\]) | Returns the chain decomposition of a graph. | --- # Centrality — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Centrality[#](#module-networkx.algorithms.centrality "Link to this heading") ============================================================================= Degree[#](#degree "Link to this heading") ------------------------------------------ | | | | --- | --- | | [`degree_centrality`](generated/networkx.algorithms.centrality.degree_centrality.html#networkx.algorithms.centrality.degree_centrality "networkx.algorithms.centrality.degree_centrality")
(G) | Compute the degree centrality for nodes. | | [`in_degree_centrality`](generated/networkx.algorithms.centrality.in_degree_centrality.html#networkx.algorithms.centrality.in_degree_centrality "networkx.algorithms.centrality.in_degree_centrality")
(G) | Compute the in-degree centrality for nodes. | | [`out_degree_centrality`](generated/networkx.algorithms.centrality.out_degree_centrality.html#networkx.algorithms.centrality.out_degree_centrality "networkx.algorithms.centrality.out_degree_centrality")
(G) | Compute the out-degree centrality for nodes. | Eigenvector[#](#eigenvector "Link to this heading") ---------------------------------------------------- | | | | --- | --- | | [`eigenvector_centrality`](generated/networkx.algorithms.centrality.eigenvector_centrality.html#networkx.algorithms.centrality.eigenvector_centrality "networkx.algorithms.centrality.eigenvector_centrality")
(G\[, max\_iter, tol, ...\]) | Compute the eigenvector centrality for the graph G. | | [`eigenvector_centrality_numpy`](generated/networkx.algorithms.centrality.eigenvector_centrality_numpy.html#networkx.algorithms.centrality.eigenvector_centrality_numpy "networkx.algorithms.centrality.eigenvector_centrality_numpy")
(G\[, weight, ...\]) | Compute the eigenvector centrality for the graph `G`. | | [`katz_centrality`](generated/networkx.algorithms.centrality.katz_centrality.html#networkx.algorithms.centrality.katz_centrality "networkx.algorithms.centrality.katz_centrality")
(G\[, alpha, beta, max\_iter, ...\]) | Compute the Katz centrality for the nodes of the graph G. | | [`katz_centrality_numpy`](generated/networkx.algorithms.centrality.katz_centrality_numpy.html#networkx.algorithms.centrality.katz_centrality_numpy "networkx.algorithms.centrality.katz_centrality_numpy")
(G\[, alpha, beta, ...\]) | Compute the Katz centrality for the graph G. | Closeness[#](#closeness "Link to this heading") ------------------------------------------------ | | | | --- | --- | | [`closeness_centrality`](generated/networkx.algorithms.centrality.closeness_centrality.html#networkx.algorithms.centrality.closeness_centrality "networkx.algorithms.centrality.closeness_centrality")
(G\[, u, distance, ...\]) | Compute closeness centrality for nodes. | | [`incremental_closeness_centrality`](generated/networkx.algorithms.centrality.incremental_closeness_centrality.html#networkx.algorithms.centrality.incremental_closeness_centrality "networkx.algorithms.centrality.incremental_closeness_centrality")
(G, edge\[, ...\]) | Incremental closeness centrality for nodes. | Current Flow Closeness[#](#current-flow-closeness "Link to this heading") -------------------------------------------------------------------------- | | | | --- | --- | | [`current_flow_closeness_centrality`](generated/networkx.algorithms.centrality.current_flow_closeness_centrality.html#networkx.algorithms.centrality.current_flow_closeness_centrality "networkx.algorithms.centrality.current_flow_closeness_centrality")
(G\[, ...\]) | Compute current-flow closeness centrality for nodes. | | [`information_centrality`](generated/networkx.algorithms.centrality.information_centrality.html#networkx.algorithms.centrality.information_centrality "networkx.algorithms.centrality.information_centrality")
(G\[, weight, dtype, ...\]) | Compute current-flow closeness centrality for nodes. | (Shortest Path) Betweenness[#](#shortest-path-betweenness "Link to this heading") ---------------------------------------------------------------------------------- | | | | --- | --- | | [`betweenness_centrality`](generated/networkx.algorithms.centrality.betweenness_centrality.html#networkx.algorithms.centrality.betweenness_centrality "networkx.algorithms.centrality.betweenness_centrality")
(G\[, k, normalized, ...\]) | Compute the shortest-path betweenness centrality for nodes. | | [`betweenness_centrality_subset`](generated/networkx.algorithms.centrality.betweenness_centrality_subset.html#networkx.algorithms.centrality.betweenness_centrality_subset "networkx.algorithms.centrality.betweenness_centrality_subset")
(G, sources, ...) | Compute betweenness centrality for a subset of nodes. | | [`edge_betweenness_centrality`](generated/networkx.algorithms.centrality.edge_betweenness_centrality.html#networkx.algorithms.centrality.edge_betweenness_centrality "networkx.algorithms.centrality.edge_betweenness_centrality")
(G\[, k, ...\]) | Compute betweenness centrality for edges. | | [`edge_betweenness_centrality_subset`](generated/networkx.algorithms.centrality.edge_betweenness_centrality_subset.html#networkx.algorithms.centrality.edge_betweenness_centrality_subset "networkx.algorithms.centrality.edge_betweenness_centrality_subset")
(G, ...\[, ...\]) | Compute betweenness centrality for edges for a subset of nodes. | Current Flow Betweenness[#](#current-flow-betweenness "Link to this heading") ------------------------------------------------------------------------------ | | | | --- | --- | | [`current_flow_betweenness_centrality`](generated/networkx.algorithms.centrality.current_flow_betweenness_centrality.html#networkx.algorithms.centrality.current_flow_betweenness_centrality "networkx.algorithms.centrality.current_flow_betweenness_centrality")
(G\[, ...\]) | Compute current-flow betweenness centrality for nodes. | | [`edge_current_flow_betweenness_centrality`](generated/networkx.algorithms.centrality.edge_current_flow_betweenness_centrality.html#networkx.algorithms.centrality.edge_current_flow_betweenness_centrality "networkx.algorithms.centrality.edge_current_flow_betweenness_centrality")
(G) | Compute current-flow betweenness centrality for edges. | | [`approximate_current_flow_betweenness_centrality`](generated/networkx.algorithms.centrality.approximate_current_flow_betweenness_centrality.html#networkx.algorithms.centrality.approximate_current_flow_betweenness_centrality "networkx.algorithms.centrality.approximate_current_flow_betweenness_centrality")
(G) | Compute the approximate current-flow betweenness centrality for nodes. | | [`current_flow_betweenness_centrality_subset`](generated/networkx.algorithms.centrality.current_flow_betweenness_centrality_subset.html#networkx.algorithms.centrality.current_flow_betweenness_centrality_subset "networkx.algorithms.centrality.current_flow_betweenness_centrality_subset")
(G, ...) | Compute current-flow betweenness centrality for subsets of nodes. | | [`edge_current_flow_betweenness_centrality_subset`](generated/networkx.algorithms.centrality.edge_current_flow_betweenness_centrality_subset.html#networkx.algorithms.centrality.edge_current_flow_betweenness_centrality_subset "networkx.algorithms.centrality.edge_current_flow_betweenness_centrality_subset")
(G, ...) | Compute current-flow betweenness centrality for edges using subsets of nodes. | Communicability Betweenness[#](#communicability-betweenness "Link to this heading") ------------------------------------------------------------------------------------ | | | | --- | --- | | [`communicability_betweenness_centrality`](generated/networkx.algorithms.centrality.communicability_betweenness_centrality.html#networkx.algorithms.centrality.communicability_betweenness_centrality "networkx.algorithms.centrality.communicability_betweenness_centrality")
(G) | Returns subgraph communicability for all pairs of nodes in G. | Group Centrality[#](#group-centrality "Link to this heading") -------------------------------------------------------------- | | | | --- | --- | | [`group_betweenness_centrality`](generated/networkx.algorithms.centrality.group_betweenness_centrality.html#networkx.algorithms.centrality.group_betweenness_centrality "networkx.algorithms.centrality.group_betweenness_centrality")
(G, C\[, ...\]) | Compute the group betweenness centrality for a group of nodes. | | [`group_closeness_centrality`](generated/networkx.algorithms.centrality.group_closeness_centrality.html#networkx.algorithms.centrality.group_closeness_centrality "networkx.algorithms.centrality.group_closeness_centrality")
(G, S\[, weight\]) | Compute the group closeness centrality for a group of nodes. | | [`group_degree_centrality`](generated/networkx.algorithms.centrality.group_degree_centrality.html#networkx.algorithms.centrality.group_degree_centrality "networkx.algorithms.centrality.group_degree_centrality")
(G, S) | Compute the group degree centrality for a group of nodes. | | [`group_in_degree_centrality`](generated/networkx.algorithms.centrality.group_in_degree_centrality.html#networkx.algorithms.centrality.group_in_degree_centrality "networkx.algorithms.centrality.group_in_degree_centrality")
(G, S) | Compute the group in-degree centrality for a group of nodes. | | [`group_out_degree_centrality`](generated/networkx.algorithms.centrality.group_out_degree_centrality.html#networkx.algorithms.centrality.group_out_degree_centrality "networkx.algorithms.centrality.group_out_degree_centrality")
(G, S) | Compute the group out-degree centrality for a group of nodes. | | [`prominent_group`](generated/networkx.algorithms.centrality.prominent_group.html#networkx.algorithms.centrality.prominent_group "networkx.algorithms.centrality.prominent_group")
(G, k\[, weight, C, ...\]) | Find the prominent group of size \\(k\\) in graph \\(G\\). | Load[#](#load "Link to this heading") -------------------------------------- | | | | --- | --- | | [`load_centrality`](generated/networkx.algorithms.centrality.load_centrality.html#networkx.algorithms.centrality.load_centrality "networkx.algorithms.centrality.load_centrality")
(G\[, v, cutoff, normalized, ...\]) | Compute load centrality for nodes. | | [`edge_load_centrality`](generated/networkx.algorithms.centrality.edge_load_centrality.html#networkx.algorithms.centrality.edge_load_centrality "networkx.algorithms.centrality.edge_load_centrality")
(G\[, cutoff\]) | Compute edge load. | Subgraph[#](#subgraph "Link to this heading") ---------------------------------------------- | | | | --- | --- | | [`subgraph_centrality`](generated/networkx.algorithms.centrality.subgraph_centrality.html#networkx.algorithms.centrality.subgraph_centrality "networkx.algorithms.centrality.subgraph_centrality")
(G) | Returns subgraph centrality for each node in G. | | [`subgraph_centrality_exp`](generated/networkx.algorithms.centrality.subgraph_centrality_exp.html#networkx.algorithms.centrality.subgraph_centrality_exp "networkx.algorithms.centrality.subgraph_centrality_exp")
(G) | Returns the subgraph centrality for each node of G. | | [`estrada_index`](generated/networkx.algorithms.centrality.estrada_index.html#networkx.algorithms.centrality.estrada_index "networkx.algorithms.centrality.estrada_index")
(G) | Returns the Estrada index of a the graph G. | Harmonic Centrality[#](#harmonic-centrality "Link to this heading") -------------------------------------------------------------------- | | | | --- | --- | | [`harmonic_centrality`](generated/networkx.algorithms.centrality.harmonic_centrality.html#networkx.algorithms.centrality.harmonic_centrality "networkx.algorithms.centrality.harmonic_centrality")
(G\[, nbunch, distance, ...\]) | Compute harmonic centrality for nodes. | Dispersion[#](#dispersion "Link to this heading") -------------------------------------------------- | | | | --- | --- | | [`dispersion`](generated/networkx.algorithms.centrality.dispersion.html#networkx.algorithms.centrality.dispersion "networkx.algorithms.centrality.dispersion")
(G\[, u, v, normalized, alpha, b, c\]) | Calculate dispersion between `u` and `v` in `G`. | Reaching[#](#reaching "Link to this heading") ---------------------------------------------- | | | | --- | --- | | [`local_reaching_centrality`](generated/networkx.algorithms.centrality.local_reaching_centrality.html#networkx.algorithms.centrality.local_reaching_centrality "networkx.algorithms.centrality.local_reaching_centrality")
(G, v\[, paths, ...\]) | Returns the local reaching centrality of a node in a directed graph. | | [`global_reaching_centrality`](generated/networkx.algorithms.centrality.global_reaching_centrality.html#networkx.algorithms.centrality.global_reaching_centrality "networkx.algorithms.centrality.global_reaching_centrality")
(G\[, weight, ...\]) | Returns the global reaching centrality of a directed graph. | Percolation[#](#percolation "Link to this heading") ---------------------------------------------------- | | | | --- | --- | | [`percolation_centrality`](generated/networkx.algorithms.centrality.percolation_centrality.html#networkx.algorithms.centrality.percolation_centrality "networkx.algorithms.centrality.percolation_centrality")
(G\[, attribute, ...\]) | Compute the percolation centrality for nodes. | Second Order Centrality[#](#second-order-centrality "Link to this heading") ---------------------------------------------------------------------------- | | | | --- | --- | | [`second_order_centrality`](generated/networkx.algorithms.centrality.second_order_centrality.html#networkx.algorithms.centrality.second_order_centrality "networkx.algorithms.centrality.second_order_centrality")
(G\[, weight\]) | Compute the second order centrality for nodes of G. | Trophic[#](#trophic "Link to this heading") -------------------------------------------- | | | | --- | --- | | [`trophic_levels`](generated/networkx.algorithms.centrality.trophic_levels.html#networkx.algorithms.centrality.trophic_levels "networkx.algorithms.centrality.trophic_levels")
(G\[, weight\]) | Compute the trophic levels of nodes. | | [`trophic_differences`](generated/networkx.algorithms.centrality.trophic_differences.html#networkx.algorithms.centrality.trophic_differences "networkx.algorithms.centrality.trophic_differences")
(G\[, weight\]) | Compute the trophic differences of the edges of a directed graph. | | [`trophic_incoherence_parameter`](generated/networkx.algorithms.centrality.trophic_incoherence_parameter.html#networkx.algorithms.centrality.trophic_incoherence_parameter "networkx.algorithms.centrality.trophic_incoherence_parameter")
(G\[, weight, ...\]) | Compute the trophic incoherence parameter of a graph. | VoteRank[#](#voterank "Link to this heading") ---------------------------------------------- | | | | --- | --- | | [`voterank`](generated/networkx.algorithms.centrality.voterank.html#networkx.algorithms.centrality.voterank "networkx.algorithms.centrality.voterank")
(G\[, number\_of\_nodes\]) | Select a list of influential nodes in a graph using VoteRank algorithm | Laplacian[#](#laplacian "Link to this heading") ------------------------------------------------ | | | | --- | --- | | [`laplacian_centrality`](generated/networkx.algorithms.centrality.laplacian_centrality.html#networkx.algorithms.centrality.laplacian_centrality "networkx.algorithms.centrality.laplacian_centrality")
(G\[, normalized, ...\]) | Compute the Laplacian centrality for nodes in the graph `G`. | On this page --- # Clustering — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Clustering[#](#module-networkx.algorithms.cluster "Link to this heading") ========================================================================== Algorithms to characterize the number of triangles in a graph. | | | | --- | --- | | [`triangles`](generated/networkx.algorithms.cluster.triangles.html#networkx.algorithms.cluster.triangles "networkx.algorithms.cluster.triangles")
(G\[, nodes\]) | Compute the number of triangles. | | [`transitivity`](generated/networkx.algorithms.cluster.transitivity.html#networkx.algorithms.cluster.transitivity "networkx.algorithms.cluster.transitivity")
(G) | Compute graph transitivity, the fraction of all possible triangles present in G. | | [`clustering`](generated/networkx.algorithms.cluster.clustering.html#networkx.algorithms.cluster.clustering "networkx.algorithms.cluster.clustering")
(G\[, nodes, weight\]) | Compute the clustering coefficient for nodes. | | [`average_clustering`](generated/networkx.algorithms.cluster.average_clustering.html#networkx.algorithms.cluster.average_clustering "networkx.algorithms.cluster.average_clustering")
(G\[, nodes, weight, ...\]) | Compute the average clustering coefficient for the graph G. | | [`square_clustering`](generated/networkx.algorithms.cluster.square_clustering.html#networkx.algorithms.cluster.square_clustering "networkx.algorithms.cluster.square_clustering")
(G\[, nodes\]) | Compute the squares clustering coefficient for nodes. | | [`generalized_degree`](generated/networkx.algorithms.cluster.generalized_degree.html#networkx.algorithms.cluster.generalized_degree "networkx.algorithms.cluster.generalized_degree")
(G\[, nodes\]) | Compute the generalized degree for nodes. | --- # Chordal — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Chordal[#](#chordal "Link to this heading") ============================================ Algorithms for chordal graphs. A graph is chordal if every cycle of length at least 4 has a chord (an edge joining two nodes not adjacent in the cycle). [https://en.wikipedia.org/wiki/Chordal\_graph](https://en.wikipedia.org/wiki/Chordal_graph) | | | | --- | --- | | [`is_chordal`](generated/networkx.algorithms.chordal.is_chordal.html#networkx.algorithms.chordal.is_chordal "networkx.algorithms.chordal.is_chordal")
(G) | Checks whether G is a chordal graph. | | [`chordal_graph_cliques`](generated/networkx.algorithms.chordal.chordal_graph_cliques.html#networkx.algorithms.chordal.chordal_graph_cliques "networkx.algorithms.chordal.chordal_graph_cliques")
(G) | Returns all maximal cliques of a chordal graph. | | [`chordal_graph_treewidth`](generated/networkx.algorithms.chordal.chordal_graph_treewidth.html#networkx.algorithms.chordal.chordal_graph_treewidth "networkx.algorithms.chordal.chordal_graph_treewidth")
(G) | Returns the treewidth of the chordal graph G. | | [`complete_to_chordal_graph`](generated/networkx.algorithms.chordal.complete_to_chordal_graph.html#networkx.algorithms.chordal.complete_to_chordal_graph "networkx.algorithms.chordal.complete_to_chordal_graph")
(G) | Return a copy of G completed to a chordal graph | | [`find_induced_nodes`](generated/networkx.algorithms.chordal.find_induced_nodes.html#networkx.algorithms.chordal.find_induced_nodes "networkx.algorithms.chordal.find_induced_nodes")
(G, s, t\[, treewidth\_bound\]) | Returns the set of induced nodes in the path from s to t. | --- # Coloring — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Coloring[#](#module-networkx.algorithms.coloring "Link to this heading") ========================================================================= | | | | --- | --- | | [`greedy_color`](generated/networkx.algorithms.coloring.greedy_color.html#networkx.algorithms.coloring.greedy_color "networkx.algorithms.coloring.greedy_color")
(G\[, strategy, interchange\]) | Color a graph using various strategies of greedy graph coloring. | | [`equitable_color`](generated/networkx.algorithms.coloring.equitable_color.html#networkx.algorithms.coloring.equitable_color "networkx.algorithms.coloring.equitable_color")
(G, num\_colors) | Provides an equitable coloring for nodes of `G`. | Some node ordering strategies are provided for use with [`greedy_color()`](generated/networkx.algorithms.coloring.greedy_color.html#networkx.algorithms.coloring.greedy_color "networkx.algorithms.coloring.greedy_color") . | | | | --- | --- | | [`strategy_connected_sequential`](generated/networkx.algorithms.coloring.strategy_connected_sequential.html#networkx.algorithms.coloring.strategy_connected_sequential "networkx.algorithms.coloring.strategy_connected_sequential")
(G, colors\[, ...\]) | Returns an iterable over nodes in `G` in the order given by a breadth-first or depth-first traversal. | | [`strategy_connected_sequential_dfs`](generated/networkx.algorithms.coloring.strategy_connected_sequential_dfs.html#networkx.algorithms.coloring.strategy_connected_sequential_dfs "networkx.algorithms.coloring.strategy_connected_sequential_dfs")
(G, colors) | Returns an iterable over nodes in `G` in the order given by a depth-first traversal. | | [`strategy_connected_sequential_bfs`](generated/networkx.algorithms.coloring.strategy_connected_sequential_bfs.html#networkx.algorithms.coloring.strategy_connected_sequential_bfs "networkx.algorithms.coloring.strategy_connected_sequential_bfs")
(G, colors) | Returns an iterable over nodes in `G` in the order given by a breadth-first traversal. | | [`strategy_independent_set`](generated/networkx.algorithms.coloring.strategy_independent_set.html#networkx.algorithms.coloring.strategy_independent_set "networkx.algorithms.coloring.strategy_independent_set")
(G, colors) | Uses a greedy independent set removal strategy to determine the colors. | | [`strategy_largest_first`](generated/networkx.algorithms.coloring.strategy_largest_first.html#networkx.algorithms.coloring.strategy_largest_first "networkx.algorithms.coloring.strategy_largest_first")
(G, colors) | Returns a list of the nodes of `G` in decreasing order by degree. | | [`strategy_random_sequential`](generated/networkx.algorithms.coloring.strategy_random_sequential.html#networkx.algorithms.coloring.strategy_random_sequential "networkx.algorithms.coloring.strategy_random_sequential")
(G, colors\[, seed\]) | Returns a random permutation of the nodes of `G` as a list. | | [`strategy_saturation_largest_first`](generated/networkx.algorithms.coloring.strategy_saturation_largest_first.html#networkx.algorithms.coloring.strategy_saturation_largest_first "networkx.algorithms.coloring.strategy_saturation_largest_first")
(G, colors) | Iterates over all the nodes of `G` in "saturation order" (also known as "DSATUR"). | | [`strategy_smallest_last`](generated/networkx.algorithms.coloring.strategy_smallest_last.html#networkx.algorithms.coloring.strategy_smallest_last "networkx.algorithms.coloring.strategy_smallest_last")
(G, colors) | Returns a deque of the nodes of `G`, "smallest" last. | --- # Clique — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Clique[#](#module-networkx.algorithms.clique "Link to this heading") ===================================================================== Functions for finding and manipulating cliques. Finding the largest clique in a graph is NP-complete problem, so most of these algorithms have an exponential running time; for more information, see the Wikipedia article on the clique problem [\[1\]](#rdf96788ab83f-1) . \[[1](#id1)\ \] clique problem:: [https://en.wikipedia.org/wiki/Clique\_problem](https://en.wikipedia.org/wiki/Clique_problem) | | | | --- | --- | | [`enumerate_all_cliques`](generated/networkx.algorithms.clique.enumerate_all_cliques.html#networkx.algorithms.clique.enumerate_all_cliques "networkx.algorithms.clique.enumerate_all_cliques")
(G) | Returns all cliques in an undirected graph. | | [`find_cliques`](generated/networkx.algorithms.clique.find_cliques.html#networkx.algorithms.clique.find_cliques "networkx.algorithms.clique.find_cliques")
(G\[, nodes\]) | Returns all maximal cliques in an undirected graph. | | [`find_cliques_recursive`](generated/networkx.algorithms.clique.find_cliques_recursive.html#networkx.algorithms.clique.find_cliques_recursive "networkx.algorithms.clique.find_cliques_recursive")
(G\[, nodes\]) | Returns all maximal cliques in a graph. | | [`make_max_clique_graph`](generated/networkx.algorithms.clique.make_max_clique_graph.html#networkx.algorithms.clique.make_max_clique_graph "networkx.algorithms.clique.make_max_clique_graph")
(G\[, create\_using\]) | Returns the maximal clique graph of the given graph. | | [`make_clique_bipartite`](generated/networkx.algorithms.clique.make_clique_bipartite.html#networkx.algorithms.clique.make_clique_bipartite "networkx.algorithms.clique.make_clique_bipartite")
(G\[, fpos, ...\]) | Returns the bipartite clique graph corresponding to `G`. | | [`node_clique_number`](generated/networkx.algorithms.clique.node_clique_number.html#networkx.algorithms.clique.node_clique_number "networkx.algorithms.clique.node_clique_number")
(G\[, nodes, cliques, ...\]) | Returns the size of the largest maximal clique containing each given node. | | [`number_of_cliques`](generated/networkx.algorithms.clique.number_of_cliques.html#networkx.algorithms.clique.number_of_cliques "networkx.algorithms.clique.number_of_cliques")
(G\[, nodes, cliques\]) | Returns the number of maximal cliques for each node. | | [`max_weight_clique`](generated/networkx.algorithms.clique.max_weight_clique.html#networkx.algorithms.clique.max_weight_clique "networkx.algorithms.clique.max_weight_clique")
(G\[, weight\]) | Find a maximum weight clique in G. | --- # Communicability — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Communicability[#](#module-networkx.algorithms.communicability_alg "Link to this heading") =========================================================================================== Communicability. | | | | --- | --- | | [`communicability`](generated/networkx.algorithms.communicability_alg.communicability.html#networkx.algorithms.communicability_alg.communicability "networkx.algorithms.communicability_alg.communicability")
(G) | Returns communicability between all pairs of nodes in G. | | [`communicability_exp`](generated/networkx.algorithms.communicability_alg.communicability_exp.html#networkx.algorithms.communicability_alg.communicability_exp "networkx.algorithms.communicability_alg.communicability_exp")
(G) | Returns communicability between all pairs of nodes in G. | --- # Communities — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Communities[#](#module-networkx.algorithms.community "Link to this heading") ============================================================================= Functions for computing and measuring community structure. The `community` subpackage can be accessed by using `networkx.community`, then accessing the functions as attributes of `community`. For example: \>>> import networkx as nx \>>> G \= nx.barbell\_graph(5, 1) \>>> communities\_generator \= nx.community.girvan\_newman(G) \>>> top\_level\_communities \= next(communities\_generator) \>>> next\_level\_communities \= next(communities\_generator) \>>> sorted(map(sorted, next\_level\_communities)) \[\[0, 1, 2, 3, 4\], \[5\], \[6, 7, 8, 9, 10\]\] Bipartitions[#](#module-networkx.algorithms.community.kernighan_lin "Link to this heading") -------------------------------------------------------------------------------------------- Functions for computing the Kernighan–Lin bipartition algorithm. | | | | --- | --- | | [`kernighan_lin_bisection`](generated/networkx.algorithms.community.kernighan_lin.kernighan_lin_bisection.html#networkx.algorithms.community.kernighan_lin.kernighan_lin_bisection "networkx.algorithms.community.kernighan_lin.kernighan_lin_bisection")
(G\[, partition, ...\]) | Partition a graph into two blocks using the Kernighan–Lin algorithm. | Divisive Communities[#](#module-networkx.algorithms.community.divisive "Link to this heading") ----------------------------------------------------------------------------------------------- | | | | --- | --- | | [`edge_betweenness_partition`](generated/networkx.algorithms.community.divisive.edge_betweenness_partition.html#networkx.algorithms.community.divisive.edge_betweenness_partition "networkx.algorithms.community.divisive.edge_betweenness_partition")
(G, number\_of\_sets, \*) | Partition created by iteratively removing the highest edge betweenness edge. | | [`edge_current_flow_betweenness_partition`](generated/networkx.algorithms.community.divisive.edge_current_flow_betweenness_partition.html#networkx.algorithms.community.divisive.edge_current_flow_betweenness_partition "networkx.algorithms.community.divisive.edge_current_flow_betweenness_partition")
(G, ...) | Partition created by removing the highest edge current flow betweenness edge. | K-Clique[#](#module-networkx.algorithms.community.kclique "Link to this heading") ---------------------------------------------------------------------------------- | | | | --- | --- | | [`k_clique_communities`](generated/networkx.algorithms.community.kclique.k_clique_communities.html#networkx.algorithms.community.kclique.k_clique_communities "networkx.algorithms.community.kclique.k_clique_communities")
(G, k\[, cliques\]) | Find k-clique communities in graph using the percolation method. | Modularity-based communities[#](#module-networkx.algorithms.community.modularity_max "Link to this heading") ------------------------------------------------------------------------------------------------------------- Functions for detecting communities based on modularity. | | | | --- | --- | | [`greedy_modularity_communities`](generated/networkx.algorithms.community.modularity_max.greedy_modularity_communities.html#networkx.algorithms.community.modularity_max.greedy_modularity_communities "networkx.algorithms.community.modularity_max.greedy_modularity_communities")
(G\[, weight, ...\]) | Find communities in G using greedy modularity maximization. | | [`naive_greedy_modularity_communities`](generated/networkx.algorithms.community.modularity_max.naive_greedy_modularity_communities.html#networkx.algorithms.community.modularity_max.naive_greedy_modularity_communities "networkx.algorithms.community.modularity_max.naive_greedy_modularity_communities")
(G\[, ...\]) | Find communities in G using greedy modularity maximization. | Tree partitioning[#](#module-networkx.algorithms.community.lukes "Link to this heading") ----------------------------------------------------------------------------------------- Lukes Algorithm for exact optimal weighted tree partitioning. | | | | --- | --- | | [`lukes_partitioning`](generated/networkx.algorithms.community.lukes.lukes_partitioning.html#networkx.algorithms.community.lukes.lukes_partitioning "networkx.algorithms.community.lukes.lukes_partitioning")
(G, max\_size\[, ...\]) | Optimal partitioning of a weighted tree using the Lukes algorithm. | Label propagation[#](#module-networkx.algorithms.community.label_propagation "Link to this heading") ----------------------------------------------------------------------------------------------------- Label propagation community detection algorithms. | | | | --- | --- | | [`asyn_lpa_communities`](generated/networkx.algorithms.community.label_propagation.asyn_lpa_communities.html#networkx.algorithms.community.label_propagation.asyn_lpa_communities "networkx.algorithms.community.label_propagation.asyn_lpa_communities")
(G\[, weight, seed\]) | Returns communities in `G` as detected by asynchronous label propagation. | | [`label_propagation_communities`](generated/networkx.algorithms.community.label_propagation.label_propagation_communities.html#networkx.algorithms.community.label_propagation.label_propagation_communities "networkx.algorithms.community.label_propagation.label_propagation_communities")
(G) | Generates community sets determined by label propagation | | [`fast_label_propagation_communities`](generated/networkx.algorithms.community.label_propagation.fast_label_propagation_communities.html#networkx.algorithms.community.label_propagation.fast_label_propagation_communities "networkx.algorithms.community.label_propagation.fast_label_propagation_communities")
(G, \*\[, ...\]) | Returns communities in `G` as detected by fast label propagation. | Louvain Community Detection[#](#module-networkx.algorithms.community.louvain "Link to this heading") ----------------------------------------------------------------------------------------------------- Function for detecting communities based on Louvain Community Detection Algorithm | | | | --- | --- | | [`louvain_communities`](generated/networkx.algorithms.community.louvain.louvain_communities.html#networkx.algorithms.community.louvain.louvain_communities "networkx.algorithms.community.louvain.louvain_communities")
(G\[, weight, resolution, ...\]) | Find the best partition of a graph using the Louvain Community Detection Algorithm. | | [`louvain_partitions`](generated/networkx.algorithms.community.louvain.louvain_partitions.html#networkx.algorithms.community.louvain.louvain_partitions "networkx.algorithms.community.louvain.louvain_partitions")
(G\[, weight, resolution, ...\]) | Yields partitions for each level of the Louvain Community Detection Algorithm | Fluid Communities[#](#module-networkx.algorithms.community.asyn_fluid "Link to this heading") ---------------------------------------------------------------------------------------------- Asynchronous Fluid Communities algorithm for community detection. | | | | --- | --- | | [`asyn_fluidc`](generated/networkx.algorithms.community.asyn_fluid.asyn_fluidc.html#networkx.algorithms.community.asyn_fluid.asyn_fluidc "networkx.algorithms.community.asyn_fluid.asyn_fluidc")
(G, k\[, max\_iter, seed\]) | Returns communities in `G` as detected by Fluid Communities algorithm. | Measuring partitions[#](#module-networkx.algorithms.community.quality "Link to this heading") ---------------------------------------------------------------------------------------------- Functions for measuring the quality of a partition (into communities). | | | | --- | --- | | [`modularity`](generated/networkx.algorithms.community.quality.modularity.html#networkx.algorithms.community.quality.modularity "networkx.algorithms.community.quality.modularity")
(G, communities\[, weight, resolution\]) | Returns the modularity of the given partition of the graph. | | [`partition_quality`](generated/networkx.algorithms.community.quality.partition_quality.html#networkx.algorithms.community.quality.partition_quality "networkx.algorithms.community.quality.partition_quality")
(G, partition) | Returns the coverage and performance of a partition of G. | Partitions via centrality measures[#](#module-networkx.algorithms.community.centrality "Link to this heading") --------------------------------------------------------------------------------------------------------------- Functions for computing communities based on centrality notions. | | | | --- | --- | | [`girvan_newman`](generated/networkx.algorithms.community.centrality.girvan_newman.html#networkx.algorithms.community.centrality.girvan_newman "networkx.algorithms.community.centrality.girvan_newman")
(G\[, most\_valuable\_edge\]) | Finds communities in a graph using the Girvan–Newman method. | Validating partitions[#](#module-networkx.algorithms.community.community_utils "Link to this heading") ------------------------------------------------------------------------------------------------------- Helper functions for community-finding algorithms. | | | | --- | --- | | [`is_partition`](generated/networkx.algorithms.community.community_utils.is_partition.html#networkx.algorithms.community.community_utils.is_partition "networkx.algorithms.community.community_utils.is_partition")
(G, communities) | Returns _True_ if `communities` is a partition of the nodes of `G`. | On this page --- # Components — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Components[#](#module-networkx.algorithms.components "Link to this heading") ============================================================================= Connectivity[#](#connectivity "Link to this heading") ------------------------------------------------------ | | | | --- | --- | | [`is_connected`](generated/networkx.algorithms.components.is_connected.html#networkx.algorithms.components.is_connected "networkx.algorithms.components.is_connected")
(G) | Returns True if the graph is connected, False otherwise. | | [`number_connected_components`](generated/networkx.algorithms.components.number_connected_components.html#networkx.algorithms.components.number_connected_components "networkx.algorithms.components.number_connected_components")
(G) | Returns the number of connected components. | | [`connected_components`](generated/networkx.algorithms.components.connected_components.html#networkx.algorithms.components.connected_components "networkx.algorithms.components.connected_components")
(G) | Generate connected components. | | [`node_connected_component`](generated/networkx.algorithms.components.node_connected_component.html#networkx.algorithms.components.node_connected_component "networkx.algorithms.components.node_connected_component")
(G, n) | Returns the set of nodes in the component of graph containing node n. | Strong connectivity[#](#strong-connectivity "Link to this heading") -------------------------------------------------------------------- | | | | --- | --- | | [`is_strongly_connected`](generated/networkx.algorithms.components.is_strongly_connected.html#networkx.algorithms.components.is_strongly_connected "networkx.algorithms.components.is_strongly_connected")
(G) | Test directed graph for strong connectivity. | | [`number_strongly_connected_components`](generated/networkx.algorithms.components.number_strongly_connected_components.html#networkx.algorithms.components.number_strongly_connected_components "networkx.algorithms.components.number_strongly_connected_components")
(G) | Returns number of strongly connected components in graph. | | [`strongly_connected_components`](generated/networkx.algorithms.components.strongly_connected_components.html#networkx.algorithms.components.strongly_connected_components "networkx.algorithms.components.strongly_connected_components")
(G) | Generate nodes in strongly connected components of graph. | | [`kosaraju_strongly_connected_components`](generated/networkx.algorithms.components.kosaraju_strongly_connected_components.html#networkx.algorithms.components.kosaraju_strongly_connected_components "networkx.algorithms.components.kosaraju_strongly_connected_components")
(G\[, ...\]) | Generate nodes in strongly connected components of graph. | | [`condensation`](generated/networkx.algorithms.components.condensation.html#networkx.algorithms.components.condensation "networkx.algorithms.components.condensation")
(G\[, scc\]) | Returns the condensation of G. | Weak connectivity[#](#weak-connectivity "Link to this heading") ---------------------------------------------------------------- | | | | --- | --- | | [`is_weakly_connected`](generated/networkx.algorithms.components.is_weakly_connected.html#networkx.algorithms.components.is_weakly_connected "networkx.algorithms.components.is_weakly_connected")
(G) | Test directed graph for weak connectivity. | | [`number_weakly_connected_components`](generated/networkx.algorithms.components.number_weakly_connected_components.html#networkx.algorithms.components.number_weakly_connected_components "networkx.algorithms.components.number_weakly_connected_components")
(G) | Returns the number of weakly connected components in G. | | [`weakly_connected_components`](generated/networkx.algorithms.components.weakly_connected_components.html#networkx.algorithms.components.weakly_connected_components "networkx.algorithms.components.weakly_connected_components")
(G) | Generate weakly connected components of G. | Attracting components[#](#attracting-components "Link to this heading") ------------------------------------------------------------------------ | | | | --- | --- | | [`is_attracting_component`](generated/networkx.algorithms.components.is_attracting_component.html#networkx.algorithms.components.is_attracting_component "networkx.algorithms.components.is_attracting_component")
(G) | Returns True if `G` consists of a single attracting component. | | [`number_attracting_components`](generated/networkx.algorithms.components.number_attracting_components.html#networkx.algorithms.components.number_attracting_components "networkx.algorithms.components.number_attracting_components")
(G) | Returns the number of attracting components in `G`. | | [`attracting_components`](generated/networkx.algorithms.components.attracting_components.html#networkx.algorithms.components.attracting_components "networkx.algorithms.components.attracting_components")
(G) | Generates the attracting components in `G`. | Biconnected components[#](#biconnected-components "Link to this heading") -------------------------------------------------------------------------- | | | | --- | --- | | [`is_biconnected`](generated/networkx.algorithms.components.is_biconnected.html#networkx.algorithms.components.is_biconnected "networkx.algorithms.components.is_biconnected")
(G) | Returns True if the graph is biconnected, False otherwise. | | [`biconnected_components`](generated/networkx.algorithms.components.biconnected_components.html#networkx.algorithms.components.biconnected_components "networkx.algorithms.components.biconnected_components")
(G) | Returns a generator of sets of nodes, one set for each biconnected component of the graph | | [`biconnected_component_edges`](generated/networkx.algorithms.components.biconnected_component_edges.html#networkx.algorithms.components.biconnected_component_edges "networkx.algorithms.components.biconnected_component_edges")
(G) | Returns a generator of lists of edges, one list for each biconnected component of the input graph. | | [`articulation_points`](generated/networkx.algorithms.components.articulation_points.html#networkx.algorithms.components.articulation_points "networkx.algorithms.components.articulation_points")
(G) | Yield the articulation points, or cut vertices, of a graph. | Semiconnectedness[#](#semiconnectedness "Link to this heading") ---------------------------------------------------------------- | | | | --- | --- | | [`is_semiconnected`](generated/networkx.algorithms.components.is_semiconnected.html#networkx.algorithms.components.is_semiconnected "networkx.algorithms.components.is_semiconnected")
(G) | Returns True if the graph is semiconnected, False otherwise. | On this page --- # Connectivity — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Connectivity[#](#module-networkx.algorithms.connectivity "Link to this heading") ================================================================================= Connectivity and cut algorithms Edge-augmentation[#](#module-networkx.algorithms.connectivity.edge_augmentation "Link to this heading") -------------------------------------------------------------------------------------------------------- Algorithms for finding k-edge-augmentations A k-edge-augmentation is a set of edges, that once added to a graph, ensures that the graph is k-edge-connected; i.e. the graph cannot be disconnected unless k or more edges are removed. Typically, the goal is to find the augmentation with minimum weight. In general, it is not guaranteed that a k-edge-augmentation exists. ### See Also[#](#see-also "Link to this heading") `edge_kcomponents` : algorithms for finding k-edge-connected components `connectivity` : algorithms for determining edge connectivity. | | | | --- | --- | | [`k_edge_augmentation`](generated/networkx.algorithms.connectivity.edge_augmentation.k_edge_augmentation.html#networkx.algorithms.connectivity.edge_augmentation.k_edge_augmentation "networkx.algorithms.connectivity.edge_augmentation.k_edge_augmentation")
(G, k\[, avail, weight, ...\]) | Finds set of edges to k-edge-connect G. | | [`is_k_edge_connected`](generated/networkx.algorithms.connectivity.edge_augmentation.is_k_edge_connected.html#networkx.algorithms.connectivity.edge_augmentation.is_k_edge_connected "networkx.algorithms.connectivity.edge_augmentation.is_k_edge_connected")
(G, k) | Tests to see if a graph is k-edge-connected. | | [`is_locally_k_edge_connected`](generated/networkx.algorithms.connectivity.edge_augmentation.is_locally_k_edge_connected.html#networkx.algorithms.connectivity.edge_augmentation.is_locally_k_edge_connected "networkx.algorithms.connectivity.edge_augmentation.is_locally_k_edge_connected")
(G, s, t, k) | Tests to see if an edge in a graph is locally k-edge-connected. | K-edge-components[#](#module-networkx.algorithms.connectivity.edge_kcomponents "Link to this heading") ------------------------------------------------------------------------------------------------------- Algorithms for finding k-edge-connected components and subgraphs. A k-edge-connected component (k-edge-cc) is a maximal set of nodes in G, such that all pairs of node have an edge-connectivity of at least k. A k-edge-connected subgraph (k-edge-subgraph) is a maximal set of nodes in G, such that the subgraph of G defined by the nodes has an edge-connectivity at least k. | | | | --- | --- | | [`k_edge_components`](generated/networkx.algorithms.connectivity.edge_kcomponents.k_edge_components.html#networkx.algorithms.connectivity.edge_kcomponents.k_edge_components "networkx.algorithms.connectivity.edge_kcomponents.k_edge_components")
(G, k) | Generates nodes in each maximal k-edge-connected component in G. | | [`k_edge_subgraphs`](generated/networkx.algorithms.connectivity.edge_kcomponents.k_edge_subgraphs.html#networkx.algorithms.connectivity.edge_kcomponents.k_edge_subgraphs "networkx.algorithms.connectivity.edge_kcomponents.k_edge_subgraphs")
(G, k) | Generates nodes in each maximal k-edge-connected subgraph in G. | | [`bridge_components`](generated/networkx.algorithms.connectivity.edge_kcomponents.bridge_components.html#networkx.algorithms.connectivity.edge_kcomponents.bridge_components "networkx.algorithms.connectivity.edge_kcomponents.bridge_components")
(G) | Finds all bridge-connected components G. | | [`EdgeComponentAuxGraph`](generated/networkx.algorithms.connectivity.edge_kcomponents.EdgeComponentAuxGraph.html#networkx.algorithms.connectivity.edge_kcomponents.EdgeComponentAuxGraph "networkx.algorithms.connectivity.edge_kcomponents.EdgeComponentAuxGraph")
() | A simple algorithm to find all k-edge-connected components in a graph. | K-node-components[#](#module-networkx.algorithms.connectivity.kcomponents "Link to this heading") -------------------------------------------------------------------------------------------------- Moody and White algorithm for k-components | | | | --- | --- | | [`k_components`](generated/networkx.algorithms.connectivity.kcomponents.k_components.html#networkx.algorithms.connectivity.kcomponents.k_components "networkx.algorithms.connectivity.kcomponents.k_components")
(G\[, flow\_func\]) | Returns the k-component structure of a graph G. | K-node-cutsets[#](#module-networkx.algorithms.connectivity.kcutsets "Link to this heading") -------------------------------------------------------------------------------------------- Kanevsky all minimum node k cutsets algorithm. | | | | --- | --- | | [`all_node_cuts`](generated/networkx.algorithms.connectivity.kcutsets.all_node_cuts.html#networkx.algorithms.connectivity.kcutsets.all_node_cuts "networkx.algorithms.connectivity.kcutsets.all_node_cuts")
(G\[, k, flow\_func\]) | Returns all minimum k cutsets of an undirected graph G. | Flow-based disjoint paths[#](#module-networkx.algorithms.connectivity.disjoint_paths "Link to this heading") ------------------------------------------------------------------------------------------------------------- Flow based node and edge disjoint paths. | | | | --- | --- | | [`edge_disjoint_paths`](generated/networkx.algorithms.connectivity.disjoint_paths.edge_disjoint_paths.html#networkx.algorithms.connectivity.disjoint_paths.edge_disjoint_paths "networkx.algorithms.connectivity.disjoint_paths.edge_disjoint_paths")
(G, s, t\[, flow\_func, ...\]) | Returns the edges disjoint paths between source and target. | | [`node_disjoint_paths`](generated/networkx.algorithms.connectivity.disjoint_paths.node_disjoint_paths.html#networkx.algorithms.connectivity.disjoint_paths.node_disjoint_paths "networkx.algorithms.connectivity.disjoint_paths.node_disjoint_paths")
(G, s, t\[, flow\_func, ...\]) | Computes node disjoint paths between source and target. | Flow-based Connectivity[#](#module-networkx.algorithms.connectivity.connectivity "Link to this heading") --------------------------------------------------------------------------------------------------------- Flow based connectivity algorithms | | | | --- | --- | | [`average_node_connectivity`](generated/networkx.algorithms.connectivity.connectivity.average_node_connectivity.html#networkx.algorithms.connectivity.connectivity.average_node_connectivity "networkx.algorithms.connectivity.connectivity.average_node_connectivity")
(G\[, flow\_func\]) | Returns the average connectivity of a graph G. | | [`all_pairs_node_connectivity`](generated/networkx.algorithms.connectivity.connectivity.all_pairs_node_connectivity.html#networkx.algorithms.connectivity.connectivity.all_pairs_node_connectivity "networkx.algorithms.connectivity.connectivity.all_pairs_node_connectivity")
(G\[, nbunch, ...\]) | Compute node connectivity between all pairs of nodes of G. | | [`edge_connectivity`](generated/networkx.algorithms.connectivity.connectivity.edge_connectivity.html#networkx.algorithms.connectivity.connectivity.edge_connectivity "networkx.algorithms.connectivity.connectivity.edge_connectivity")
(G\[, s, t, flow\_func, cutoff\]) | Returns the edge connectivity of the graph or digraph G. | | [`local_edge_connectivity`](generated/networkx.algorithms.connectivity.connectivity.local_edge_connectivity.html#networkx.algorithms.connectivity.connectivity.local_edge_connectivity "networkx.algorithms.connectivity.connectivity.local_edge_connectivity")
(G, s, t\[, ...\]) | Returns local edge connectivity for nodes s and t in G. | | [`local_node_connectivity`](generated/networkx.algorithms.connectivity.connectivity.local_node_connectivity.html#networkx.algorithms.connectivity.connectivity.local_node_connectivity "networkx.algorithms.connectivity.connectivity.local_node_connectivity")
(G, s, t\[, ...\]) | Computes local node connectivity for nodes s and t. | | [`node_connectivity`](generated/networkx.algorithms.connectivity.connectivity.node_connectivity.html#networkx.algorithms.connectivity.connectivity.node_connectivity "networkx.algorithms.connectivity.connectivity.node_connectivity")
(G\[, s, t, flow\_func\]) | Returns node connectivity for a graph or digraph G. | Flow-based Minimum Cuts[#](#module-networkx.algorithms.connectivity.cuts "Link to this heading") ------------------------------------------------------------------------------------------------- Flow based cut algorithms | | | | --- | --- | | [`minimum_edge_cut`](generated/networkx.algorithms.connectivity.cuts.minimum_edge_cut.html#networkx.algorithms.connectivity.cuts.minimum_edge_cut "networkx.algorithms.connectivity.cuts.minimum_edge_cut")
(G\[, s, t, flow\_func\]) | Returns a set of edges of minimum cardinality that disconnects G. | | [`minimum_node_cut`](generated/networkx.algorithms.connectivity.cuts.minimum_node_cut.html#networkx.algorithms.connectivity.cuts.minimum_node_cut "networkx.algorithms.connectivity.cuts.minimum_node_cut")
(G\[, s, t, flow\_func\]) | Returns a set of nodes of minimum cardinality that disconnects G. | | [`minimum_st_edge_cut`](generated/networkx.algorithms.connectivity.cuts.minimum_st_edge_cut.html#networkx.algorithms.connectivity.cuts.minimum_st_edge_cut "networkx.algorithms.connectivity.cuts.minimum_st_edge_cut")
(G, s, t\[, flow\_func, ...\]) | Returns the edges of the cut-set of a minimum (s, t)-cut. | | [`minimum_st_node_cut`](generated/networkx.algorithms.connectivity.cuts.minimum_st_node_cut.html#networkx.algorithms.connectivity.cuts.minimum_st_node_cut "networkx.algorithms.connectivity.cuts.minimum_st_node_cut")
(G, s, t\[, flow\_func, ...\]) | Returns a set of nodes of minimum cardinality that disconnect source from target in G. | Stoer-Wagner minimum cut[#](#module-networkx.algorithms.connectivity.stoerwagner "Link to this heading") --------------------------------------------------------------------------------------------------------- Stoer-Wagner minimum cut algorithm. | | | | --- | --- | | [`stoer_wagner`](generated/networkx.algorithms.connectivity.stoerwagner.stoer_wagner.html#networkx.algorithms.connectivity.stoerwagner.stoer_wagner "networkx.algorithms.connectivity.stoerwagner.stoer_wagner")
(G\[, weight, heap\]) | Returns the weighted minimum edge cut using the Stoer-Wagner algorithm. | Utils for flow-based connectivity[#](#module-networkx.algorithms.connectivity.utils "Link to this heading") ------------------------------------------------------------------------------------------------------------ Utilities for connectivity package | | | | --- | --- | | [`build_auxiliary_edge_connectivity`](generated/networkx.algorithms.connectivity.utils.build_auxiliary_edge_connectivity.html#networkx.algorithms.connectivity.utils.build_auxiliary_edge_connectivity "networkx.algorithms.connectivity.utils.build_auxiliary_edge_connectivity")
(G) | Auxiliary digraph for computing flow based edge connectivity | | [`build_auxiliary_node_connectivity`](generated/networkx.algorithms.connectivity.utils.build_auxiliary_node_connectivity.html#networkx.algorithms.connectivity.utils.build_auxiliary_node_connectivity "networkx.algorithms.connectivity.utils.build_auxiliary_node_connectivity")
(G) | Creates a directed graph D from an undirected graph G to compute flow based node connectivity. | On this page --- # Cores — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Cores[#](#module-networkx.algorithms.core "Link to this heading") ================================================================== Find the k-cores of a graph. The k-core is found by recursively pruning nodes with degrees less than k. See the following references for details: An O(m) Algorithm for Cores Decomposition of Networks Vladimir Batagelj and Matjaz Zaversnik, 2003. [https://arxiv.org/abs/cs.DS/0310049](https://arxiv.org/abs/cs.DS/0310049) Generalized Cores Vladimir Batagelj and Matjaz Zaversnik, 2002. [https://arxiv.org/pdf/cs/0202039](https://arxiv.org/pdf/cs/0202039) For directed graphs a more general notion is that of D-cores which looks at (k, l) restrictions on (in, out) degree. The (k, k) D-core is the k-core. D-cores: Measuring Collaboration of Directed Graphs Based on Degeneracy Christos Giatsidis, Dimitrios M. Thilikos, Michalis Vazirgiannis, ICDM 2011. [http://www.graphdegeneracy.org/dcores\_ICDM\_2011.pdf](http://www.graphdegeneracy.org/dcores_ICDM_2011.pdf) Multi-scale structure and topological anomaly detection via a new network statistic: The onion decomposition L. Hébert-Dufresne, J. A. Grochow, and A. Allard Scientific Reports 6, 31708 (2016) [http://doi.org/10.1038/srep31708](http://doi.org/10.1038/srep31708) | | | | --- | --- | | [`core_number`](generated/networkx.algorithms.core.core_number.html#networkx.algorithms.core.core_number "networkx.algorithms.core.core_number")
(G) | Returns the core number for each node. | | [`k_core`](generated/networkx.algorithms.core.k_core.html#networkx.algorithms.core.k_core "networkx.algorithms.core.k_core")
(G\[, k, core\_number\]) | Returns the k-core of G. | | [`k_shell`](generated/networkx.algorithms.core.k_shell.html#networkx.algorithms.core.k_shell "networkx.algorithms.core.k_shell")
(G\[, k, core\_number\]) | Returns the k-shell of G. | | [`k_crust`](generated/networkx.algorithms.core.k_crust.html#networkx.algorithms.core.k_crust "networkx.algorithms.core.k_crust")
(G\[, k, core\_number\]) | Returns the k-crust of G. | | [`k_corona`](generated/networkx.algorithms.core.k_corona.html#networkx.algorithms.core.k_corona "networkx.algorithms.core.k_corona")
(G, k\[, core\_number\]) | Returns the k-corona of G. | | [`k_truss`](generated/networkx.algorithms.core.k_truss.html#networkx.algorithms.core.k_truss "networkx.algorithms.core.k_truss")
(G, k) | Returns the k-truss of `G`. | | [`onion_layers`](generated/networkx.algorithms.core.onion_layers.html#networkx.algorithms.core.onion_layers "networkx.algorithms.core.onion_layers")
(G) | Returns the layer of each vertex in an onion decomposition of the graph. | --- # Covering — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Covering[#](#module-networkx.algorithms.covering "Link to this heading") ========================================================================= Functions related to graph covers. | | | | --- | --- | | [`min_edge_cover`](generated/networkx.algorithms.covering.min_edge_cover.html#networkx.algorithms.covering.min_edge_cover "networkx.algorithms.covering.min_edge_cover")
(G\[, matching\_algorithm\]) | Returns the min cardinality edge cover of the graph as a set of edges. | | [`is_edge_cover`](generated/networkx.algorithms.covering.is_edge_cover.html#networkx.algorithms.covering.is_edge_cover "networkx.algorithms.covering.is_edge_cover")
(G, cover) | Decides whether a set of edges is a valid edge cover of the graph. | --- # Cycles — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Cycles[#](#module-networkx.algorithms.cycles "Link to this heading") ===================================================================== | | | | --- | --- | | [`cycle_basis`](generated/networkx.algorithms.cycles.cycle_basis.html#networkx.algorithms.cycles.cycle_basis "networkx.algorithms.cycles.cycle_basis")
(G\[, root\]) | Returns a list of cycles which form a basis for cycles of G. | | [`simple_cycles`](generated/networkx.algorithms.cycles.simple_cycles.html#networkx.algorithms.cycles.simple_cycles "networkx.algorithms.cycles.simple_cycles")
(G\[, length\_bound\]) | Find simple cycles (elementary circuits) of a graph. | | [`recursive_simple_cycles`](generated/networkx.algorithms.cycles.recursive_simple_cycles.html#networkx.algorithms.cycles.recursive_simple_cycles "networkx.algorithms.cycles.recursive_simple_cycles")
(G) | Find simple cycles (elementary circuits) of a directed graph. | | [`find_cycle`](generated/networkx.algorithms.cycles.find_cycle.html#networkx.algorithms.cycles.find_cycle "networkx.algorithms.cycles.find_cycle")
(G\[, source, orientation\]) | Returns a cycle found via depth-first traversal. | | [`minimum_cycle_basis`](generated/networkx.algorithms.cycles.minimum_cycle_basis.html#networkx.algorithms.cycles.minimum_cycle_basis "networkx.algorithms.cycles.minimum_cycle_basis")
(G\[, weight\]) | Returns a minimum weight cycle basis for G | | [`chordless_cycles`](generated/networkx.algorithms.cycles.chordless_cycles.html#networkx.algorithms.cycles.chordless_cycles "networkx.algorithms.cycles.chordless_cycles")
(G\[, length\_bound\]) | Find simple chordless cycles of a graph. | | [`girth`](generated/networkx.algorithms.cycles.girth.html#networkx.algorithms.cycles.girth "networkx.algorithms.cycles.girth")
(G) | Returns the girth of the graph. | --- # Cuts — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Cuts[#](#module-networkx.algorithms.cuts "Link to this heading") ================================================================= Functions for finding and evaluating cuts in a graph. | | | | --- | --- | | [`boundary_expansion`](generated/networkx.algorithms.cuts.boundary_expansion.html#networkx.algorithms.cuts.boundary_expansion "networkx.algorithms.cuts.boundary_expansion")
(G, S) | Returns the boundary expansion of the set `S`. | | [`conductance`](generated/networkx.algorithms.cuts.conductance.html#networkx.algorithms.cuts.conductance "networkx.algorithms.cuts.conductance")
(G, S\[, T, weight\]) | Returns the conductance of two sets of nodes. | | [`cut_size`](generated/networkx.algorithms.cuts.cut_size.html#networkx.algorithms.cuts.cut_size "networkx.algorithms.cuts.cut_size")
(G, S\[, T, weight\]) | Returns the size of the cut between two sets of nodes. | | [`edge_expansion`](generated/networkx.algorithms.cuts.edge_expansion.html#networkx.algorithms.cuts.edge_expansion "networkx.algorithms.cuts.edge_expansion")
(G, S\[, T, weight\]) | Returns the edge expansion between two node sets. | | [`mixing_expansion`](generated/networkx.algorithms.cuts.mixing_expansion.html#networkx.algorithms.cuts.mixing_expansion "networkx.algorithms.cuts.mixing_expansion")
(G, S\[, T, weight\]) | Returns the mixing expansion between two node sets. | | [`node_expansion`](generated/networkx.algorithms.cuts.node_expansion.html#networkx.algorithms.cuts.node_expansion "networkx.algorithms.cuts.node_expansion")
(G, S) | Returns the node expansion of the set `S`. | | [`normalized_cut_size`](generated/networkx.algorithms.cuts.normalized_cut_size.html#networkx.algorithms.cuts.normalized_cut_size "networkx.algorithms.cuts.normalized_cut_size")
(G, S\[, T, weight\]) | Returns the normalized size of the cut between two sets of nodes. | | [`volume`](generated/networkx.algorithms.cuts.volume.html#networkx.algorithms.cuts.volume "networkx.algorithms.cuts.volume")
(G, S\[, weight\]) | Returns the volume of a set of nodes. | --- # Distance-Regular Graphs — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Distance-Regular Graphs[#](#module-networkx.algorithms.distance_regular "Link to this heading") ================================================================================================ | | | | --- | --- | | [`is_distance_regular`](generated/networkx.algorithms.distance_regular.is_distance_regular.html#networkx.algorithms.distance_regular.is_distance_regular "networkx.algorithms.distance_regular.is_distance_regular")
(G) | Returns True if the graph is distance regular, False otherwise. | | [`is_strongly_regular`](generated/networkx.algorithms.distance_regular.is_strongly_regular.html#networkx.algorithms.distance_regular.is_strongly_regular "networkx.algorithms.distance_regular.is_strongly_regular")
(G) | Returns True if and only if the given graph is strongly regular. | | [`intersection_array`](generated/networkx.algorithms.distance_regular.intersection_array.html#networkx.algorithms.distance_regular.intersection_array "networkx.algorithms.distance_regular.intersection_array")
(G) | Returns the intersection array of a distance-regular graph. | | [`global_parameters`](generated/networkx.algorithms.distance_regular.global_parameters.html#networkx.algorithms.distance_regular.global_parameters "networkx.algorithms.distance_regular.global_parameters")
(b, c) | Returns global parameters for a given intersection array. | --- # D-Separation — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") D-Separation[#](#module-networkx.algorithms.d_separation "Link to this heading") ================================================================================= Algorithm for testing d-separation in DAGs. _d-separation_ is a test for conditional independence in probability distributions that can be factorized using DAGs. It is a purely graphical test that uses the underlying graph and makes no reference to the actual distribution parameters. See [\[1\]](#re62631f30934-1) for a formal definition. The implementation is based on the conceptually simple linear time algorithm presented in [\[2\]](#re62631f30934-2) . Refer to [\[3\]](#re62631f30934-3) , [\[4\]](#re62631f30934-4) for a couple of alternative algorithms. The functional interface in NetworkX consists of three functions: * [`find_minimal_d_separator`](generated/networkx.algorithms.d_separation.find_minimal_d_separator.html#networkx.algorithms.d_separation.find_minimal_d_separator "networkx.algorithms.d_separation.find_minimal_d_separator") returns a minimal d-separator set `z`. That is, removing any node or nodes from it makes it no longer a d-separator. * [`is_d_separator`](generated/networkx.algorithms.d_separation.is_d_separator.html#networkx.algorithms.d_separation.is_d_separator "networkx.algorithms.d_separation.is_d_separator") checks if a given set is a d-separator. * [`is_minimal_d_separator`](generated/networkx.algorithms.d_separation.is_minimal_d_separator.html#networkx.algorithms.d_separation.is_minimal_d_separator "networkx.algorithms.d_separation.is_minimal_d_separator") checks if a given set is a minimal d-separator. D-separators[#](#d-separators "Link to this heading") ------------------------------------------------------ Here, we provide a brief overview of d-separation and related concepts that are relevant for understanding it: The ideas of d-separation and d-connection relate to paths being open or blocked. * A “path” is a sequence of nodes connected in order by edges. Unlike for most graph theory analysis, the direction of the edges is ignored. Thus the path can be thought of as a traditional path on the undirected version of the graph. * A “candidate d-separator” `z` is a set of nodes being considered as possibly blocking all paths between two prescribed sets `x` and `y` of nodes. We refer to each node in the candidate d-separator as “known”. * A “collider” node on a path is a node that is a successor of its two neighbor nodes on the path. That is, `c` is a collider if the edge directions along the path look like `... u -> c <- v ...`. * If a collider node or any of its descendants are “known”, the collider is called an “open collider”. Otherwise it is a “blocking collider”. * Any path can be “blocked” in two ways. If the path contains a “known” node that is not a collider, the path is blocked. Also, if the path contains a collider that is not a “known” node, the path is blocked. * A path is “open” if it is not blocked. That is, it is open if every node is either an open collider or not a “known”. Said another way, every “known” in the path is a collider and every collider is open (has a “known” as a inclusive descendant). The concept of “open path” is meant to demonstrate a probabilistic conditional dependence between two nodes given prescribed knowledge (“known” nodes). * Two sets `x` and `y` of nodes are “d-separated” by a set of nodes `z` if all paths between nodes in `x` and nodes in `y` are blocked. That is, if there are no open paths from any node in `x` to any node in `y`. Such a set `z` is a “d-separator” of `x` and `y`. * A “minimal d-separator” is a d-separator `z` for which no node or subset of nodes can be removed with it still being a d-separator. The d-separator blocks some paths between `x` and `y` but opens others. Nodes in the d-separator block paths if the nodes are not colliders. But if a collider or its descendant nodes are in the d-separation set, the colliders are open, allowing a path through that collider. Illustration of D-separation with examples[#](#illustration-of-d-separation-with-examples "Link to this heading") ------------------------------------------------------------------------------------------------------------------ A pair of two nodes, `u` and `v`, are d-connected if there is a path from `u` to `v` that is not blocked. That means, there is an open path from `u` to `v`. For example, if the d-separating set is the empty set, then the following paths are open between `u` and `v`: * u <- n -> v * u -> w -> … -> n -> v If on the other hand, `n` is in the d-separating set, then `n` blocks those paths between `u` and `v`. Colliders block a path if they and their descendants are not included in the d-separating set. An example of a path that is blocked when the d-separating set is empty is: * u -> w -> … -> n <- v The node `n` is a collider in this path and is not in the d-separating set. So `n` blocks this path. However, if `n` or a descendant of `n` is included in the d-separating set, then the path through the collider at `n` (… -> n <- …) is “open”. D-separation is concerned with blocking all paths between nodes from `x` to `y`. A d-separating set between `x` and `y` is one where all paths are blocked. D-separation and its applications in probability[#](#d-separation-and-its-applications-in-probability "Link to this heading") ------------------------------------------------------------------------------------------------------------------------------ D-separation is commonly used in probabilistic causal-graph models. D-separation connects the idea of probabilistic “dependence” with separation in a graph. If one assumes the causal Markov condition [\[5\]](#re62631f30934-5) , (every node is conditionally independent of its non-descendants, given its parents) then d-separation implies conditional independence in probability distributions. Symmetrically, d-connection implies dependence. The intuition is as follows. The edges on a causal graph indicate which nodes influence the outcome of other nodes directly. An edge from u to v implies that the outcome of event `u` influences the probabilities for the outcome of event `v`. Certainly knowing `u` changes predictions for `v`. But also knowing `v` changes predictions for `u`. The outcomes are dependent. Furthermore, an edge from `v` to `w` would mean that `w` and `v` are dependent and thus that `u` could indirectly influence `w`. Without any knowledge about the system (candidate d-separating set is empty) a causal graph `u -> v -> w` allows all three nodes to be dependent. But if we know the outcome of `v`, the conditional probabilities of outcomes for `u` and `w` are independent of each other. That is, once we know the outcome for ``` `v`, the probabilities for ``w ``` do not depend on the outcome for `u`. This is the idea behind `v` blocking the path if it is “known” (in the candidate d-separating set). The same argument works whether the direction of the edges are both left-going and when both arrows head out from the middle. Having a “known” node on a path blocks the collider-free path because those relationships make the conditional probabilities independent. The direction of the causal edges does impact dependence precisely in the case of a collider e.g. `u -> v <- w`. In that situation, both `u` and `w` influence `` v` ``. But they do not directly influence each other. So without any knowledge of any outcomes, `u` and `w` are independent. That is the idea behind colliders blocking the path. But, if `v` is known, the conditional probabilities of `u` and `w` can be dependent. This is the heart of Berkson’s Paradox [\[6\]](#re62631f30934-6) . For example, suppose `u` and `w` are boolean events (they either happen or do not) and `v` represents the outcome “at least one of `u` and `w` occur”. Then knowing `v` is true makes the conditional probabilities of `u` and `w` dependent. Essentially, knowing that at least one of them is true raises the probability of each. But further knowledge that `w` is true (or false) change the conditional probability of `u` to either the original value or 1. So the conditional probability of `u` depends on the outcome of `w` even though there is no causal relationship between them. When a collider is known, dependence can occur across paths through that collider. This is the reason open colliders do not block paths. Furthermore, even if `v` is not “known”, if one of its descendants is “known” we can use that information to know more about `v` which again makes `u` and `w` potentially dependent. Suppose the chance of `n` occurring is much higher when `v` occurs (“at least one of `u` and `w` occur”). Then if we know `n` occurred, it is more likely that `v` occurred and that makes the chance of `u` and `w` dependent. This is the idea behind why a collider does no block a path if any descendant of the collider is “known”. When two sets of nodes `x` and `y` are d-separated by a set `z`, it means that given the outcomes of the nodes in `z`, the probabilities of outcomes of the nodes in `x` are independent of the outcomes of the nodes in `y` and vice versa. Examples[#](#examples "Link to this heading") ---------------------------------------------- A Hidden Markov Model with 5 observed states and 5 hidden states where the hidden states have causal relationships resulting in a path results in the following causal network. We check that early states along the path are separated from late state in the path by the d-separator of the middle hidden state. Thus if we condition on the middle hidden state, the early state probabilities are independent of the late state outcomes. \>>> G \= nx.DiGraph() \>>> G.add\_edges\_from( ... \[\ ... ("H1", "H2"),\ ... ("H2", "H3"),\ ... ("H3", "H4"),\ ... ("H4", "H5"),\ ... ("H1", "O1"),\ ... ("H2", "O2"),\ ... ("H3", "O3"),\ ... ("H4", "O4"),\ ... ("H5", "O5"),\ ... \] ... ) \>>> x, y, z \= ({"H1", "O1"}, {"H5", "O5"}, {"H3"}) \>>> nx.is\_d\_separator(G, x, y, z) True \>>> nx.is\_minimal\_d\_separator(G, x, y, z) True \>>> nx.is\_minimal\_d\_separator(G, x, y, z | {"O3"}) False \>>> z \= nx.find\_minimal\_d\_separator(G, x | y, {"O2", "O3", "O4"}) \>>> z \== {"H2", "H4"} True If no minimal\_d\_separator exists, [`None`](https://docs.python.org/3/library/constants.html#None "(in Python v3.13)") is returned \>>> other\_z \= nx.find\_minimal\_d\_separator(G, x | y, {"H2", "H3"}) \>>> other\_z is None True References[#](#references "Link to this heading") -------------------------------------------------- \[[1](#id1)\ \] Pearl, J. (2009). Causality. Cambridge: Cambridge University Press. \[[2](#id2)\ \] Darwiche, A. (2009). Modeling and reasoning with Bayesian networks. Cambridge: Cambridge University Press. \[[3](#id3)\ \] Shachter, Ross D. “Bayes-ball: The rational pastime (for determining irrelevance and requisite information in belief networks and influence diagrams).” In Proceedings of the Fourteenth Conference on Uncertainty in Artificial Intelligence (UAI), (pp. 480–487). 1998. \[[4](#id4)\ \] Koller, D., & Friedman, N. (2009). Probabilistic graphical models: principles and techniques. The MIT Press. \[[5](#id5)\ \] [https://en.wikipedia.org/wiki/Causal\_Markov\_condition](https://en.wikipedia.org/wiki/Causal_Markov_condition) \[[6](#id6)\ \] [https://en.wikipedia.org/wiki/Berkson%27s\_paradox](https://en.wikipedia.org/wiki/Berkson%27s_paradox) | | | | --- | --- | | [`is_d_separator`](generated/networkx.algorithms.d_separation.is_d_separator.html#networkx.algorithms.d_separation.is_d_separator "networkx.algorithms.d_separation.is_d_separator")
(G, x, y, z) | Return whether node sets `x` and `y` are d-separated by `z`. | | [`is_minimal_d_separator`](generated/networkx.algorithms.d_separation.is_minimal_d_separator.html#networkx.algorithms.d_separation.is_minimal_d_separator "networkx.algorithms.d_separation.is_minimal_d_separator")
(G, x, y, z, \*\[, ...\]) | Determine if `z` is a minimal d-separator for `x` and `y`. | | [`find_minimal_d_separator`](generated/networkx.algorithms.d_separation.find_minimal_d_separator.html#networkx.algorithms.d_separation.find_minimal_d_separator "networkx.algorithms.d_separation.find_minimal_d_separator")
(G, x, y, \*\[, ...\]) | Returns a minimal d-separating set between `x` and `y` if possible | On this page --- # Dominance — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Dominance[#](#module-networkx.algorithms.dominance "Link to this heading") =========================================================================== Dominance algorithms. | | | | --- | --- | | [`immediate_dominators`](generated/networkx.algorithms.dominance.immediate_dominators.html#networkx.algorithms.dominance.immediate_dominators "networkx.algorithms.dominance.immediate_dominators")
(G, start) | Returns the immediate dominators of all nodes of a directed graph. | | [`dominance_frontiers`](generated/networkx.algorithms.dominance.dominance_frontiers.html#networkx.algorithms.dominance.dominance_frontiers "networkx.algorithms.dominance.dominance_frontiers")
(G, start) | Returns the dominance frontiers of all nodes of a directed graph. | --- # Directed Acyclic Graphs — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Directed Acyclic Graphs[#](#module-networkx.algorithms.dag "Link to this heading") =================================================================================== Algorithms for directed acyclic graphs (DAGs). Note that most of these functions are only guaranteed to work for DAGs. In general, these functions do not check for acyclic-ness, so it is up to the user to check for that. | | | | --- | --- | | [`ancestors`](generated/networkx.algorithms.dag.ancestors.html#networkx.algorithms.dag.ancestors "networkx.algorithms.dag.ancestors")
(G, source) | Returns all nodes having a path to `source` in `G`. | | [`descendants`](generated/networkx.algorithms.dag.descendants.html#networkx.algorithms.dag.descendants "networkx.algorithms.dag.descendants")
(G, source) | Returns all nodes reachable from `source` in `G`. | | [`topological_sort`](generated/networkx.algorithms.dag.topological_sort.html#networkx.algorithms.dag.topological_sort "networkx.algorithms.dag.topological_sort")
(G) | Returns a generator of nodes in topologically sorted order. | | [`topological_generations`](generated/networkx.algorithms.dag.topological_generations.html#networkx.algorithms.dag.topological_generations "networkx.algorithms.dag.topological_generations")
(G) | Stratifies a DAG into generations. | | [`all_topological_sorts`](generated/networkx.algorithms.dag.all_topological_sorts.html#networkx.algorithms.dag.all_topological_sorts "networkx.algorithms.dag.all_topological_sorts")
(G) | Returns a generator of \_all\_ topological sorts of the directed graph G. | | [`lexicographical_topological_sort`](generated/networkx.algorithms.dag.lexicographical_topological_sort.html#networkx.algorithms.dag.lexicographical_topological_sort "networkx.algorithms.dag.lexicographical_topological_sort")
(G\[, key\]) | Generate the nodes in the unique lexicographical topological sort order. | | [`is_directed_acyclic_graph`](generated/networkx.algorithms.dag.is_directed_acyclic_graph.html#networkx.algorithms.dag.is_directed_acyclic_graph "networkx.algorithms.dag.is_directed_acyclic_graph")
(G) | Returns True if the graph `G` is a directed acyclic graph (DAG) or False if not. | | [`is_aperiodic`](generated/networkx.algorithms.dag.is_aperiodic.html#networkx.algorithms.dag.is_aperiodic "networkx.algorithms.dag.is_aperiodic")
(G) | Returns True if `G` is aperiodic. | | [`transitive_closure`](generated/networkx.algorithms.dag.transitive_closure.html#networkx.algorithms.dag.transitive_closure "networkx.algorithms.dag.transitive_closure")
(G\[, reflexive\]) | Returns transitive closure of a graph | | [`transitive_closure_dag`](generated/networkx.algorithms.dag.transitive_closure_dag.html#networkx.algorithms.dag.transitive_closure_dag "networkx.algorithms.dag.transitive_closure_dag")
(G\[, topo\_order\]) | Returns the transitive closure of a directed acyclic graph. | | [`transitive_reduction`](generated/networkx.algorithms.dag.transitive_reduction.html#networkx.algorithms.dag.transitive_reduction "networkx.algorithms.dag.transitive_reduction")
(G) | Returns transitive reduction of a directed graph | | [`antichains`](generated/networkx.algorithms.dag.antichains.html#networkx.algorithms.dag.antichains "networkx.algorithms.dag.antichains")
(G\[, topo\_order\]) | Generates antichains from a directed acyclic graph (DAG). | | [`dag_longest_path`](generated/networkx.algorithms.dag.dag_longest_path.html#networkx.algorithms.dag.dag_longest_path "networkx.algorithms.dag.dag_longest_path")
(G\[, weight, ...\]) | Returns the longest path in a directed acyclic graph (DAG). | | [`dag_longest_path_length`](generated/networkx.algorithms.dag.dag_longest_path_length.html#networkx.algorithms.dag.dag_longest_path_length "networkx.algorithms.dag.dag_longest_path_length")
(G\[, weight, ...\]) | Returns the longest path length in a DAG | | [`dag_to_branching`](generated/networkx.algorithms.dag.dag_to_branching.html#networkx.algorithms.dag.dag_to_branching "networkx.algorithms.dag.dag_to_branching")
(G) | Returns a branching representing all (overlapping) paths from root nodes to leaf nodes in the given directed acyclic graph. | | [`compute_v_structures`](generated/networkx.algorithms.dag.compute_v_structures.html#networkx.algorithms.dag.compute_v_structures "networkx.algorithms.dag.compute_v_structures")
(G) | Yields 3-node tuples that represent the v-structures in `G`. | | [`colliders`](generated/networkx.algorithms.dag.colliders.html#networkx.algorithms.dag.colliders "networkx.algorithms.dag.colliders")
(G) | Yields 3-node tuples that represent the colliders in `G`. | | [`v_structures`](generated/networkx.algorithms.dag.v_structures.html#networkx.algorithms.dag.v_structures "networkx.algorithms.dag.v_structures")
(G) | Yields 3-node tuples that represent the v-structures in `G`. | --- # Dominating Sets — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Dominating Sets[#](#module-networkx.algorithms.dominating "Link to this heading") ================================================================================== Functions for computing dominating sets in a graph. | | | | --- | --- | | [`dominating_set`](generated/networkx.algorithms.dominating.dominating_set.html#networkx.algorithms.dominating.dominating_set "networkx.algorithms.dominating.dominating_set")
(G\[, start\_with\]) | Finds a dominating set for the graph G. | | [`is_dominating_set`](generated/networkx.algorithms.dominating.is_dominating_set.html#networkx.algorithms.dominating.is_dominating_set "networkx.algorithms.dominating.is_dominating_set")
(G, nbunch) | Checks if `nbunch` is a dominating set for `G`. | --- # Distance Measures — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Distance Measures[#](#module-networkx.algorithms.distance_measures "Link to this heading") =========================================================================================== Graph diameter, radius, eccentricity and other properties. | | | | --- | --- | | [`barycenter`](generated/networkx.algorithms.distance_measures.barycenter.html#networkx.algorithms.distance_measures.barycenter "networkx.algorithms.distance_measures.barycenter")
(G\[, weight, attr, sp\]) | Calculate barycenter of a connected graph, optionally with edge weights. | | [`center`](generated/networkx.algorithms.distance_measures.center.html#networkx.algorithms.distance_measures.center "networkx.algorithms.distance_measures.center")
(G\[, e, usebounds, weight\]) | Returns the center of the graph G. | | [`diameter`](generated/networkx.algorithms.distance_measures.diameter.html#networkx.algorithms.distance_measures.diameter "networkx.algorithms.distance_measures.diameter")
(G\[, e, usebounds, weight\]) | Returns the diameter of the graph G. | | [`harmonic_diameter`](generated/networkx.algorithms.distance_measures.harmonic_diameter.html#networkx.algorithms.distance_measures.harmonic_diameter "networkx.algorithms.distance_measures.harmonic_diameter")
(G\[, sp\]) | Returns the harmonic diameter of the graph G. | | [`eccentricity`](generated/networkx.algorithms.distance_measures.eccentricity.html#networkx.algorithms.distance_measures.eccentricity "networkx.algorithms.distance_measures.eccentricity")
(G\[, v, sp, weight\]) | Returns the eccentricity of nodes in G. | | [`effective_graph_resistance`](generated/networkx.algorithms.distance_measures.effective_graph_resistance.html#networkx.algorithms.distance_measures.effective_graph_resistance "networkx.algorithms.distance_measures.effective_graph_resistance")
(G\[, weight, ...\]) | Returns the Effective graph resistance of G. | | [`kemeny_constant`](generated/networkx.algorithms.distance_measures.kemeny_constant.html#networkx.algorithms.distance_measures.kemeny_constant "networkx.algorithms.distance_measures.kemeny_constant")
(G, \*\[, weight\]) | Returns the Kemeny constant of the given graph. | | [`periphery`](generated/networkx.algorithms.distance_measures.periphery.html#networkx.algorithms.distance_measures.periphery "networkx.algorithms.distance_measures.periphery")
(G\[, e, usebounds, weight\]) | Returns the periphery of the graph G. | | [`radius`](generated/networkx.algorithms.distance_measures.radius.html#networkx.algorithms.distance_measures.radius "networkx.algorithms.distance_measures.radius")
(G\[, e, usebounds, weight\]) | Returns the radius of the graph G. | | [`resistance_distance`](generated/networkx.algorithms.distance_measures.resistance_distance.html#networkx.algorithms.distance_measures.resistance_distance "networkx.algorithms.distance_measures.resistance_distance")
(G\[, nodeA, nodeB, ...\]) | Returns the resistance distance between pairs of nodes in graph G. | --- # Efficiency — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Efficiency[#](#module-networkx.algorithms.efficiency_measures "Link to this heading") ====================================================================================== Provides functions for computing the efficiency of nodes and graphs. | | | | --- | --- | | [`efficiency`](generated/networkx.algorithms.efficiency_measures.efficiency.html#networkx.algorithms.efficiency_measures.efficiency "networkx.algorithms.efficiency_measures.efficiency")
(G, u, v) | Returns the efficiency of a pair of nodes in a graph. | | [`local_efficiency`](generated/networkx.algorithms.efficiency_measures.local_efficiency.html#networkx.algorithms.efficiency_measures.local_efficiency "networkx.algorithms.efficiency_measures.local_efficiency")
(G) | Returns the average local efficiency of the graph. | | [`global_efficiency`](generated/networkx.algorithms.efficiency_measures.global_efficiency.html#networkx.algorithms.efficiency_measures.global_efficiency "networkx.algorithms.efficiency_measures.global_efficiency")
(G) | Returns the average global efficiency of the graph. | --- # Eulerian — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Eulerian[#](#module-networkx.algorithms.euler "Link to this heading") ====================================================================== Eulerian circuits and graphs. | | | | --- | --- | | [`is_eulerian`](generated/networkx.algorithms.euler.is_eulerian.html#networkx.algorithms.euler.is_eulerian "networkx.algorithms.euler.is_eulerian")
(G) | Returns True if and only if `G` is Eulerian. | | [`eulerian_circuit`](generated/networkx.algorithms.euler.eulerian_circuit.html#networkx.algorithms.euler.eulerian_circuit "networkx.algorithms.euler.eulerian_circuit")
(G\[, source, keys\]) | Returns an iterator over the edges of an Eulerian circuit in `G`. | | [`eulerize`](generated/networkx.algorithms.euler.eulerize.html#networkx.algorithms.euler.eulerize "networkx.algorithms.euler.eulerize")
(G) | Transforms a graph into an Eulerian graph. | | [`is_semieulerian`](generated/networkx.algorithms.euler.is_semieulerian.html#networkx.algorithms.euler.is_semieulerian "networkx.algorithms.euler.is_semieulerian")
(G) | Return True iff `G` is semi-Eulerian. | | [`has_eulerian_path`](generated/networkx.algorithms.euler.has_eulerian_path.html#networkx.algorithms.euler.has_eulerian_path "networkx.algorithms.euler.has_eulerian_path")
(G\[, source\]) | Return True iff `G` has an Eulerian path. | | [`eulerian_path`](generated/networkx.algorithms.euler.eulerian_path.html#networkx.algorithms.euler.eulerian_path "networkx.algorithms.euler.eulerian_path")
(G\[, source, keys\]) | Return an iterator over the edges of an Eulerian path in `G`. | --- # Flows — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Flows[#](#module-networkx.algorithms.flow "Link to this heading") ================================================================== Maximum Flow[#](#maximum-flow "Link to this heading") ------------------------------------------------------ | | | | --- | --- | | [`maximum_flow`](generated/networkx.algorithms.flow.maximum_flow.html#networkx.algorithms.flow.maximum_flow "networkx.algorithms.flow.maximum_flow")
(flowG, \_s, \_t\[, capacity, ...\]) | Find a maximum single-commodity flow. | | [`maximum_flow_value`](generated/networkx.algorithms.flow.maximum_flow_value.html#networkx.algorithms.flow.maximum_flow_value "networkx.algorithms.flow.maximum_flow_value")
(flowG, \_s, \_t\[, ...\]) | Find the value of maximum single-commodity flow. | | [`minimum_cut`](generated/networkx.algorithms.flow.minimum_cut.html#networkx.algorithms.flow.minimum_cut "networkx.algorithms.flow.minimum_cut")
(flowG, \_s, \_t\[, capacity, flow\_func\]) | Compute the value and the node partition of a minimum (s, t)-cut. | | [`minimum_cut_value`](generated/networkx.algorithms.flow.minimum_cut_value.html#networkx.algorithms.flow.minimum_cut_value "networkx.algorithms.flow.minimum_cut_value")
(flowG, \_s, \_t\[, capacity, ...\]) | Compute the value of a minimum (s, t)-cut. | Edmonds-Karp[#](#edmonds-karp "Link to this heading") ------------------------------------------------------ | | | | --- | --- | | [`edmonds_karp`](generated/networkx.algorithms.flow.edmonds_karp.html#networkx.algorithms.flow.edmonds_karp "networkx.algorithms.flow.edmonds_karp")
(G, s, t\[, capacity, residual, ...\]) | Find a maximum single-commodity flow using the Edmonds-Karp algorithm. | Shortest Augmenting Path[#](#shortest-augmenting-path "Link to this heading") ------------------------------------------------------------------------------ | | | | --- | --- | | [`shortest_augmenting_path`](generated/networkx.algorithms.flow.shortest_augmenting_path.html#networkx.algorithms.flow.shortest_augmenting_path "networkx.algorithms.flow.shortest_augmenting_path")
(G, s, t\[, ...\]) | Find a maximum single-commodity flow using the shortest augmenting path algorithm. | Preflow-Push[#](#preflow-push "Link to this heading") ------------------------------------------------------ | | | | --- | --- | | [`preflow_push`](generated/networkx.algorithms.flow.preflow_push.html#networkx.algorithms.flow.preflow_push "networkx.algorithms.flow.preflow_push")
(G, s, t\[, capacity, residual, ...\]) | Find a maximum single-commodity flow using the highest-label preflow-push algorithm. | Dinitz[#](#dinitz "Link to this heading") ------------------------------------------ | | | | --- | --- | | [`dinitz`](generated/networkx.algorithms.flow.dinitz.html#networkx.algorithms.flow.dinitz "networkx.algorithms.flow.dinitz")
(G, s, t\[, capacity, residual, ...\]) | Find a maximum single-commodity flow using Dinitz' algorithm. | Boykov-Kolmogorov[#](#boykov-kolmogorov "Link to this heading") ---------------------------------------------------------------- | | | | --- | --- | | [`boykov_kolmogorov`](generated/networkx.algorithms.flow.boykov_kolmogorov.html#networkx.algorithms.flow.boykov_kolmogorov "networkx.algorithms.flow.boykov_kolmogorov")
(G, s, t\[, capacity, ...\]) | Find a maximum single-commodity flow using Boykov-Kolmogorov algorithm. | Gomory-Hu Tree[#](#gomory-hu-tree "Link to this heading") ---------------------------------------------------------- | | | | --- | --- | | [`gomory_hu_tree`](generated/networkx.algorithms.flow.gomory_hu_tree.html#networkx.algorithms.flow.gomory_hu_tree "networkx.algorithms.flow.gomory_hu_tree")
(G\[, capacity, flow\_func\]) | Returns the Gomory-Hu tree of an undirected graph G. | Utils[#](#utils "Link to this heading") ---------------------------------------- | | | | --- | --- | | [`build_residual_network`](generated/networkx.algorithms.flow.build_residual_network.html#networkx.algorithms.flow.build_residual_network "networkx.algorithms.flow.build_residual_network")
(G, capacity) | Build a residual network and initialize a zero flow. | Network Simplex[#](#network-simplex "Link to this heading") ------------------------------------------------------------ | | | | --- | --- | | [`network_simplex`](generated/networkx.algorithms.flow.network_simplex.html#networkx.algorithms.flow.network_simplex "networkx.algorithms.flow.network_simplex")
(G\[, demand, capacity, weight\]) | Find a minimum cost flow satisfying all demands in digraph G. | | [`min_cost_flow_cost`](generated/networkx.algorithms.flow.min_cost_flow_cost.html#networkx.algorithms.flow.min_cost_flow_cost "networkx.algorithms.flow.min_cost_flow_cost")
(G\[, demand, capacity, weight\]) | Find the cost of a minimum cost flow satisfying all demands in digraph G. | | [`min_cost_flow`](generated/networkx.algorithms.flow.min_cost_flow.html#networkx.algorithms.flow.min_cost_flow "networkx.algorithms.flow.min_cost_flow")
(G\[, demand, capacity, weight\]) | Returns a minimum cost flow satisfying all demands in digraph G. | | [`cost_of_flow`](generated/networkx.algorithms.flow.cost_of_flow.html#networkx.algorithms.flow.cost_of_flow "networkx.algorithms.flow.cost_of_flow")
(G, flowDict\[, weight\]) | Compute the cost of the flow given by flowDict on graph G. | | [`max_flow_min_cost`](generated/networkx.algorithms.flow.max_flow_min_cost.html#networkx.algorithms.flow.max_flow_min_cost "networkx.algorithms.flow.max_flow_min_cost")
(G, s, t\[, capacity, weight\]) | Returns a maximum (s, t)-flow of minimum cost. | Capacity Scaling Minimum Cost Flow[#](#capacity-scaling-minimum-cost-flow "Link to this heading") -------------------------------------------------------------------------------------------------- | | | | --- | --- | | [`capacity_scaling`](generated/networkx.algorithms.flow.capacity_scaling.html#networkx.algorithms.flow.capacity_scaling "networkx.algorithms.flow.capacity_scaling")
(G\[, demand, capacity, ...\]) | Find a minimum cost flow satisfying all demands in digraph G. | On this page --- # Graphical degree sequence — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Graphical degree sequence[#](#module-networkx.algorithms.graphical "Link to this heading") =========================================================================================== Test sequences for graphiness. | | | | --- | --- | | [`is_graphical`](generated/networkx.algorithms.graphical.is_graphical.html#networkx.algorithms.graphical.is_graphical "networkx.algorithms.graphical.is_graphical")
(sequence\[, method\]) | Returns True if sequence is a valid degree sequence. | | [`is_digraphical`](generated/networkx.algorithms.graphical.is_digraphical.html#networkx.algorithms.graphical.is_digraphical "networkx.algorithms.graphical.is_digraphical")
(in\_sequence, out\_sequence) | Returns True if some directed graph can realize the in- and out-degree sequences. | | [`is_multigraphical`](generated/networkx.algorithms.graphical.is_multigraphical.html#networkx.algorithms.graphical.is_multigraphical "networkx.algorithms.graphical.is_multigraphical")
(sequence) | Returns True if some multigraph can realize the sequence. | | [`is_pseudographical`](generated/networkx.algorithms.graphical.is_pseudographical.html#networkx.algorithms.graphical.is_pseudographical "networkx.algorithms.graphical.is_pseudographical")
(sequence) | Returns True if some pseudograph can realize the sequence. | | [`is_valid_degree_sequence_havel_hakimi`](generated/networkx.algorithms.graphical.is_valid_degree_sequence_havel_hakimi.html#networkx.algorithms.graphical.is_valid_degree_sequence_havel_hakimi "networkx.algorithms.graphical.is_valid_degree_sequence_havel_hakimi")
(...) | Returns True if deg\_sequence can be realized by a simple graph. | | [`is_valid_degree_sequence_erdos_gallai`](generated/networkx.algorithms.graphical.is_valid_degree_sequence_erdos_gallai.html#networkx.algorithms.graphical.is_valid_degree_sequence_erdos_gallai "networkx.algorithms.graphical.is_valid_degree_sequence_erdos_gallai")
(...) | Returns True if deg\_sequence can be realized by a simple graph. | --- # Graph Hashing — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Graph Hashing[#](#module-networkx.algorithms.graph_hashing "Link to this heading") =================================================================================== Functions for hashing graphs to strings. Isomorphic graphs should be assigned identical hashes. For now, only Weisfeiler-Lehman hashing is implemented. | | | | --- | --- | | [`weisfeiler_lehman_graph_hash`](generated/networkx.algorithms.graph_hashing.weisfeiler_lehman_graph_hash.html#networkx.algorithms.graph_hashing.weisfeiler_lehman_graph_hash "networkx.algorithms.graph_hashing.weisfeiler_lehman_graph_hash")
(G\[, edge\_attr, ...\]) | Return Weisfeiler Lehman (WL) graph hash. | | [`weisfeiler_lehman_subgraph_hashes`](generated/networkx.algorithms.graph_hashing.weisfeiler_lehman_subgraph_hashes.html#networkx.algorithms.graph_hashing.weisfeiler_lehman_subgraph_hashes "networkx.algorithms.graph_hashing.weisfeiler_lehman_subgraph_hashes")
(G\[, ...\]) | Return a dictionary of subgraph hashes by node. | --- # Hierarchy — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Hierarchy[#](#module-networkx.algorithms.hierarchy "Link to this heading") =========================================================================== Flow Hierarchy. | | | | --- | --- | | [`flow_hierarchy`](generated/networkx.algorithms.hierarchy.flow_hierarchy.html#networkx.algorithms.hierarchy.flow_hierarchy "networkx.algorithms.hierarchy.flow_hierarchy")
(G\[, weight\]) | Returns the flow hierarchy of a directed network. | --- # Hybrid — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Hybrid[#](#module-networkx.algorithms.hybrid "Link to this heading") ===================================================================== Provides functions for finding and testing for locally `(k, l)`\-connected graphs. | | | | --- | --- | | [`kl_connected_subgraph`](generated/networkx.algorithms.hybrid.kl_connected_subgraph.html#networkx.algorithms.hybrid.kl_connected_subgraph "networkx.algorithms.hybrid.kl_connected_subgraph")
(G, k, l\[, low\_memory, ...\]) | Returns the maximum locally `(k, l)`\-connected subgraph of `G`. | | [`is_kl_connected`](generated/networkx.algorithms.hybrid.is_kl_connected.html#networkx.algorithms.hybrid.is_kl_connected "networkx.algorithms.hybrid.is_kl_connected")
(G, k, l\[, low\_memory\]) | Returns True if and only if `G` is locally `(k, l)`\-connected. | --- # Isolates — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Isolates[#](#module-networkx.algorithms.isolate "Link to this heading") ======================================================================== Functions for identifying isolate (degree zero) nodes. | | | | --- | --- | | [`is_isolate`](generated/networkx.algorithms.isolate.is_isolate.html#networkx.algorithms.isolate.is_isolate "networkx.algorithms.isolate.is_isolate")
(G, n) | Determines whether a node is an isolate. | | [`isolates`](generated/networkx.algorithms.isolate.isolates.html#networkx.algorithms.isolate.isolates "networkx.algorithms.isolate.isolates")
(G) | Iterator over isolates in the graph. | | [`number_of_isolates`](generated/networkx.algorithms.isolate.number_of_isolates.html#networkx.algorithms.isolate.number_of_isolates "networkx.algorithms.isolate.number_of_isolates")
(G) | Returns the number of isolates in the graph. | --- # Link Analysis — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Link Analysis[#](#link-analysis "Link to this heading") ======================================================== PageRank[#](#module-networkx.algorithms.link_analysis.pagerank_alg "Link to this heading") ------------------------------------------------------------------------------------------- PageRank analysis of graph structure. | | | | --- | --- | | [`pagerank`](generated/networkx.algorithms.link_analysis.pagerank_alg.pagerank.html#networkx.algorithms.link_analysis.pagerank_alg.pagerank "networkx.algorithms.link_analysis.pagerank_alg.pagerank")
(G\[, alpha, personalization, ...\]) | Returns the PageRank of the nodes in the graph. | | [`google_matrix`](generated/networkx.algorithms.link_analysis.pagerank_alg.google_matrix.html#networkx.algorithms.link_analysis.pagerank_alg.google_matrix "networkx.algorithms.link_analysis.pagerank_alg.google_matrix")
(G\[, alpha, personalization, ...\]) | Returns the Google matrix of the graph. | Hits[#](#module-networkx.algorithms.link_analysis.hits_alg "Link to this heading") ----------------------------------------------------------------------------------- Hubs and authorities analysis of graph structure. | | | | --- | --- | | [`hits`](generated/networkx.algorithms.link_analysis.hits_alg.hits.html#networkx.algorithms.link_analysis.hits_alg.hits "networkx.algorithms.link_analysis.hits_alg.hits")
(G\[, max\_iter, tol, nstart, normalized\]) | Returns HITS hubs and authorities values for nodes. | On this page --- # Isomorphism — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Isomorphism[#](#networkx-algorithms-isomorphism-isomorph "Link to this heading") ================================================================================= | | | | --- | --- | | [`is_isomorphic`](generated/networkx.algorithms.isomorphism.is_isomorphic.html#networkx.algorithms.isomorphism.is_isomorphic "networkx.algorithms.isomorphism.is_isomorphic")
(G1, G2\[, node\_match, edge\_match\]) | Returns True if the graphs G1 and G2 are isomorphic and False otherwise. | | [`could_be_isomorphic`](generated/networkx.algorithms.isomorphism.could_be_isomorphic.html#networkx.algorithms.isomorphism.could_be_isomorphic "networkx.algorithms.isomorphism.could_be_isomorphic")
(G1, G2) | Returns False if graphs are definitely not isomorphic. | | [`fast_could_be_isomorphic`](generated/networkx.algorithms.isomorphism.fast_could_be_isomorphic.html#networkx.algorithms.isomorphism.fast_could_be_isomorphic "networkx.algorithms.isomorphism.fast_could_be_isomorphic")
(G1, G2) | Returns False if graphs are definitely not isomorphic. | | [`faster_could_be_isomorphic`](generated/networkx.algorithms.isomorphism.faster_could_be_isomorphic.html#networkx.algorithms.isomorphism.faster_could_be_isomorphic "networkx.algorithms.isomorphism.faster_could_be_isomorphic")
(G1, G2) | Returns False if graphs are definitely not isomorphic. | VF2++[#](#module-networkx.algorithms.isomorphism.vf2pp "Link to this heading") ------------------------------------------------------------------------------- ### VF2++ Algorithm[#](#vf2-algorithm "Link to this heading") An implementation of the VF2++ algorithm [\[1\]](#r5cfb786f69d9-1) for Graph Isomorphism testing. The simplest interface to use this module is to call: [`vf2pp_is_isomorphic`](generated/networkx.algorithms.isomorphism.vf2pp.vf2pp_is_isomorphic.html#networkx.algorithms.isomorphism.vf2pp.vf2pp_is_isomorphic "networkx.algorithms.isomorphism.vf2pp.vf2pp_is_isomorphic") : to check whether two graphs are isomorphic. [`vf2pp_isomorphism`](generated/networkx.algorithms.isomorphism.vf2pp.vf2pp_isomorphism.html#networkx.algorithms.isomorphism.vf2pp.vf2pp_isomorphism "networkx.algorithms.isomorphism.vf2pp.vf2pp_isomorphism") : to obtain the node mapping between two graphs, in case they are isomorphic. [`vf2pp_all_isomorphisms`](generated/networkx.algorithms.isomorphism.vf2pp.vf2pp_all_isomorphisms.html#networkx.algorithms.isomorphism.vf2pp.vf2pp_all_isomorphisms "networkx.algorithms.isomorphism.vf2pp.vf2pp_all_isomorphisms") : to generate all possible mappings between two graphs, if isomorphic. #### Introduction[#](#introduction "Link to this heading") The VF2++ algorithm, follows a similar logic to that of VF2, while also introducing new easy-to-check cutting rules and determining the optimal access order of nodes. It is also implemented in a non-recursive manner, which saves both time and space, when compared to its previous counterpart. The optimal node ordering is obtained after taking into consideration both the degree but also the label rarity of each node. This way we place the nodes that are more likely to match, first in the order, thus examining the most promising branches in the beginning. The rules also consider node labels, making it easier to prune unfruitful branches early in the process. #### Examples[#](#examples "Link to this heading") Suppose G1 and G2 are Isomorphic Graphs. Verification is as follows: Without node labels: \>>> import networkx as nx \>>> G1 \= nx.path\_graph(4) \>>> G2 \= nx.path\_graph(4) \>>> nx.vf2pp\_is\_isomorphic(G1, G2, node\_label\=None) True \>>> nx.vf2pp\_isomorphism(G1, G2, node\_label\=None) {1: 1, 2: 2, 0: 0, 3: 3} With node labels: \>>> G1 \= nx.path\_graph(4) \>>> G2 \= nx.path\_graph(4) \>>> mapped \= {1: 1, 2: 2, 3: 3, 0: 0} \>>> nx.set\_node\_attributes( ... G1, dict(zip(G1, \["blue", "red", "green", "yellow"\])), "label" ... ) \>>> nx.set\_node\_attributes( ... G2, ... dict(zip(\[mapped\[u\] for u in G1\], \["blue", "red", "green", "yellow"\])), ... "label", ... ) \>>> nx.vf2pp\_is\_isomorphic(G1, G2, node\_label\="label") True \>>> nx.vf2pp\_isomorphism(G1, G2, node\_label\="label") {1: 1, 2: 2, 0: 0, 3: 3} #### References[#](#references "Link to this heading") \[[1](#id2)\ \] Jüttner, Alpár & Madarasi, Péter. (2018). “VF2++—An improved subgraph isomorphism algorithm”. Discrete Applied Mathematics. 242. [https://doi.org/10.1016/j.dam.2018.02.018](https://doi.org/10.1016/j.dam.2018.02.018) | | | | --- | --- | | [`vf2pp_is_isomorphic`](generated/networkx.algorithms.isomorphism.vf2pp.vf2pp_is_isomorphic.html#networkx.algorithms.isomorphism.vf2pp.vf2pp_is_isomorphic "networkx.algorithms.isomorphism.vf2pp.vf2pp_is_isomorphic")
(G1, G2\[, node\_label, ...\]) | Examines whether G1 and G2 are isomorphic. | | [`vf2pp_all_isomorphisms`](generated/networkx.algorithms.isomorphism.vf2pp.vf2pp_all_isomorphisms.html#networkx.algorithms.isomorphism.vf2pp.vf2pp_all_isomorphisms "networkx.algorithms.isomorphism.vf2pp.vf2pp_all_isomorphisms")
(G1, G2\[, node\_label, ...\]) | Yields all the possible mappings between G1 and G2. | | [`vf2pp_isomorphism`](generated/networkx.algorithms.isomorphism.vf2pp.vf2pp_isomorphism.html#networkx.algorithms.isomorphism.vf2pp.vf2pp_isomorphism "networkx.algorithms.isomorphism.vf2pp.vf2pp_isomorphism")
(G1, G2\[, node\_label, ...\]) | Return an isomorphic mapping between `G1` and `G2` if it exists. | Tree Isomorphism[#](#module-networkx.algorithms.isomorphism.tree_isomorphism "Link to this heading") ----------------------------------------------------------------------------------------------------- An algorithm for finding if two undirected trees are isomorphic, and if so returns an isomorphism between the two sets of nodes. This algorithm uses a routine to tell if two rooted trees (trees with a specified root node) are isomorphic, which may be independently useful. This implements an algorithm from: The Design and Analysis of Computer Algorithms by Aho, Hopcroft, and Ullman Addison-Wesley Publishing 1974 Example 3.2 pp. 84-86. A more understandable version of this algorithm is described in: Homework Assignment 5 McGill University SOCS 308-250B, Winter 2002 by Matthew Suderman [http://crypto.cs.mcgill.ca/~crepeau/CS250/2004/HW5+.pdf](http://crypto.cs.mcgill.ca/~crepeau/CS250/2004/HW5+.pdf) | | | | --- | --- | | [`rooted_tree_isomorphism`](generated/networkx.algorithms.isomorphism.tree_isomorphism.rooted_tree_isomorphism.html#networkx.algorithms.isomorphism.tree_isomorphism.rooted_tree_isomorphism "networkx.algorithms.isomorphism.tree_isomorphism.rooted_tree_isomorphism")
(t1, root1, t2, root2) | Given two rooted trees `t1` and `t2`, with roots `root1` and `root2` respectively this routine will determine if they are isomorphic. | | [`tree_isomorphism`](generated/networkx.algorithms.isomorphism.tree_isomorphism.tree_isomorphism.html#networkx.algorithms.isomorphism.tree_isomorphism.tree_isomorphism "networkx.algorithms.isomorphism.tree_isomorphism.tree_isomorphism")
(t1, t2) | Given two undirected (or free) trees `t1` and `t2`, this routine will determine if they are isomorphic. | Advanced Interfaces[#](#advanced-interfaces "Link to this heading") -------------------------------------------------------------------- * [VF2 Algorithm](isomorphism.vf2.html) * [Introduction](isomorphism.vf2.html#introduction) * [Examples](isomorphism.vf2.html#examples) * [Subgraph Isomorphism](isomorphism.vf2.html#subgraph-isomorphism) * [References](isomorphism.vf2.html#references) * [See Also](isomorphism.vf2.html#see-also) * [Notes](isomorphism.vf2.html#notes) * [Graph Matcher](isomorphism.vf2.html#graph-matcher) * [DiGraph Matcher](isomorphism.vf2.html#digraph-matcher) * [Match helpers](isomorphism.vf2.html#match-helpers) * [ISMAGS Algorithm](isomorphism.ismags.html) * [Notes](isomorphism.ismags.html#notes) * [References](isomorphism.ismags.html#references) * [ISMAGS object](isomorphism.ismags.html#ismags-object) * [networkx.algorithms.isomorphism.ISMAGS](generated/networkx.algorithms.isomorphism.ISMAGS.html) On this page --- # Lowest Common Ancestor — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Lowest Common Ancestor[#](#module-networkx.algorithms.lowest_common_ancestors "Link to this heading") ====================================================================================================== Algorithms for finding the lowest common ancestor of trees and DAGs. | | | | --- | --- | | [`all_pairs_lowest_common_ancestor`](generated/networkx.algorithms.lowest_common_ancestors.all_pairs_lowest_common_ancestor.html#networkx.algorithms.lowest_common_ancestors.all_pairs_lowest_common_ancestor "networkx.algorithms.lowest_common_ancestors.all_pairs_lowest_common_ancestor")
(G\[, pairs\]) | Return the lowest common ancestor of all pairs or the provided pairs | | [`tree_all_pairs_lowest_common_ancestor`](generated/networkx.algorithms.lowest_common_ancestors.tree_all_pairs_lowest_common_ancestor.html#networkx.algorithms.lowest_common_ancestors.tree_all_pairs_lowest_common_ancestor "networkx.algorithms.lowest_common_ancestors.tree_all_pairs_lowest_common_ancestor")
(G\[, ...\]) | Yield the lowest common ancestor for sets of pairs in a tree. | | [`lowest_common_ancestor`](generated/networkx.algorithms.lowest_common_ancestors.lowest_common_ancestor.html#networkx.algorithms.lowest_common_ancestors.lowest_common_ancestor "networkx.algorithms.lowest_common_ancestors.lowest_common_ancestor")
(G, node1, node2\[, ...\]) | Compute the lowest common ancestor of the given pair of nodes. | --- # Link Prediction — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Link Prediction[#](#module-networkx.algorithms.link_prediction "Link to this heading") ======================================================================================= Link prediction algorithms. | | | | --- | --- | | [`resource_allocation_index`](generated/networkx.algorithms.link_prediction.resource_allocation_index.html#networkx.algorithms.link_prediction.resource_allocation_index "networkx.algorithms.link_prediction.resource_allocation_index")
(G\[, ebunch\]) | Compute the resource allocation index of all node pairs in ebunch. | | [`jaccard_coefficient`](generated/networkx.algorithms.link_prediction.jaccard_coefficient.html#networkx.algorithms.link_prediction.jaccard_coefficient "networkx.algorithms.link_prediction.jaccard_coefficient")
(G\[, ebunch\]) | Compute the Jaccard coefficient of all node pairs in ebunch. | | [`adamic_adar_index`](generated/networkx.algorithms.link_prediction.adamic_adar_index.html#networkx.algorithms.link_prediction.adamic_adar_index "networkx.algorithms.link_prediction.adamic_adar_index")
(G\[, ebunch\]) | Compute the Adamic-Adar index of all node pairs in ebunch. | | [`preferential_attachment`](generated/networkx.algorithms.link_prediction.preferential_attachment.html#networkx.algorithms.link_prediction.preferential_attachment "networkx.algorithms.link_prediction.preferential_attachment")
(G\[, ebunch\]) | Compute the preferential attachment score of all node pairs in ebunch. | | [`cn_soundarajan_hopcroft`](generated/networkx.algorithms.link_prediction.cn_soundarajan_hopcroft.html#networkx.algorithms.link_prediction.cn_soundarajan_hopcroft "networkx.algorithms.link_prediction.cn_soundarajan_hopcroft")
(G\[, ebunch, community\]) | Count the number of common neighbors of all node pairs in ebunch | | [`ra_index_soundarajan_hopcroft`](generated/networkx.algorithms.link_prediction.ra_index_soundarajan_hopcroft.html#networkx.algorithms.link_prediction.ra_index_soundarajan_hopcroft "networkx.algorithms.link_prediction.ra_index_soundarajan_hopcroft")
(G\[, ebunch, ...\]) | Compute the resource allocation index of all node pairs in ebunch using community information. | | [`within_inter_cluster`](generated/networkx.algorithms.link_prediction.within_inter_cluster.html#networkx.algorithms.link_prediction.within_inter_cluster "networkx.algorithms.link_prediction.within_inter_cluster")
(G\[, ebunch, delta, ...\]) | Compute the ratio of within- and inter-cluster common neighbors of all node pairs in ebunch. | | [`common_neighbor_centrality`](generated/networkx.algorithms.link_prediction.common_neighbor_centrality.html#networkx.algorithms.link_prediction.common_neighbor_centrality "networkx.algorithms.link_prediction.common_neighbor_centrality")
(G\[, ebunch, alpha\]) | Return the CCPA score for each pair of nodes. | --- # Matching — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Matching[#](#module-networkx.algorithms.matching "Link to this heading") ========================================================================= Functions for computing and verifying matchings in a graph. | | | | --- | --- | | [`is_matching`](generated/networkx.algorithms.matching.is_matching.html#networkx.algorithms.matching.is_matching "networkx.algorithms.matching.is_matching")
(G, matching) | Return True if `matching` is a valid matching of `G` | | [`is_maximal_matching`](generated/networkx.algorithms.matching.is_maximal_matching.html#networkx.algorithms.matching.is_maximal_matching "networkx.algorithms.matching.is_maximal_matching")
(G, matching) | Return True if `matching` is a maximal matching of `G` | | [`is_perfect_matching`](generated/networkx.algorithms.matching.is_perfect_matching.html#networkx.algorithms.matching.is_perfect_matching "networkx.algorithms.matching.is_perfect_matching")
(G, matching) | Return True if `matching` is a perfect matching for `G` | | [`maximal_matching`](generated/networkx.algorithms.matching.maximal_matching.html#networkx.algorithms.matching.maximal_matching "networkx.algorithms.matching.maximal_matching")
(G) | Find a maximal matching in the graph. | | [`max_weight_matching`](generated/networkx.algorithms.matching.max_weight_matching.html#networkx.algorithms.matching.max_weight_matching "networkx.algorithms.matching.max_weight_matching")
(G\[, maxcardinality, weight\]) | Compute a maximum-weighted matching of G. | | [`min_weight_matching`](generated/networkx.algorithms.matching.min_weight_matching.html#networkx.algorithms.matching.min_weight_matching "networkx.algorithms.matching.min_weight_matching")
(G\[, weight\]) | Computing a minimum-weight maximal matching of G. | --- # Minors — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Minors[#](#module-networkx.algorithms.minors "Link to this heading") ===================================================================== Subpackages related to graph-minor problems. In graph theory, an undirected graph H is called a minor of the graph G if H can be formed from G by deleting edges and vertices and by contracting edges [\[1\]](#r1ebe86ef0634-1) . References[#](#references "Link to this heading") -------------------------------------------------- \[[1](#id1)\ \] [https://en.wikipedia.org/wiki/Graph\_minor](https://en.wikipedia.org/wiki/Graph_minor) | | | | --- | --- | | [`contracted_edge`](generated/networkx.algorithms.minors.contracted_edge.html#networkx.algorithms.minors.contracted_edge "networkx.algorithms.minors.contracted_edge")
(G, edge\[, self\_loops, copy\]) | Returns the graph that results from contracting the specified edge. | | [`contracted_nodes`](generated/networkx.algorithms.minors.contracted_nodes.html#networkx.algorithms.minors.contracted_nodes "networkx.algorithms.minors.contracted_nodes")
(G, u, v\[, self\_loops, copy\]) | Returns the graph that results from contracting `u` and `v`. | | [`identified_nodes`](generated/networkx.algorithms.minors.identified_nodes.html#networkx.algorithms.minors.identified_nodes "networkx.algorithms.minors.identified_nodes")
(G, u, v\[, self\_loops, copy\]) | Returns the graph that results from contracting `u` and `v`. | | [`equivalence_classes`](generated/networkx.algorithms.minors.equivalence_classes.html#networkx.algorithms.minors.equivalence_classes "networkx.algorithms.minors.equivalence_classes")
(iterable, relation) | Returns equivalence classes of `relation` when applied to `iterable`. | | [`quotient_graph`](generated/networkx.algorithms.minors.quotient_graph.html#networkx.algorithms.minors.quotient_graph "networkx.algorithms.minors.quotient_graph")
(G, partition\[, ...\]) | Returns the quotient graph of `G` under the specified equivalence relation on nodes. | On this page --- # Maximal independent set — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Maximal independent set[#](#module-networkx.algorithms.mis "Link to this heading") =================================================================================== Algorithm to find a maximal (not maximum) independent set. | | | | --- | --- | | [`maximal_independent_set`](generated/networkx.algorithms.mis.maximal_independent_set.html#networkx.algorithms.mis.maximal_independent_set "networkx.algorithms.mis.maximal_independent_set")
(G\[, nodes, seed\]) | Returns a random maximal independent set guaranteed to contain a given set of nodes. | --- # Moral — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Moral[#](#module-networkx.algorithms.moral "Link to this heading") =================================================================== Function for computing the moral graph of a directed graph. | | | | --- | --- | | [`moral_graph`](generated/networkx.algorithms.moral.moral_graph.html#networkx.algorithms.moral.moral_graph "networkx.algorithms.moral.moral_graph")
(G) | Return the Moral Graph | --- # Operators — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Operators[#](#operators "Link to this heading") ================================================ Unary operations on graphs | | | | --- | --- | | [`complement`](generated/networkx.algorithms.operators.unary.complement.html#networkx.algorithms.operators.unary.complement "networkx.algorithms.operators.unary.complement")
(G) | Returns the graph complement of G. | | [`reverse`](generated/networkx.algorithms.operators.unary.reverse.html#networkx.algorithms.operators.unary.reverse "networkx.algorithms.operators.unary.reverse")
(G\[, copy\]) | Returns the reverse directed graph of G. | Operations on graphs including union, intersection, difference. | | | | --- | --- | | [`compose`](generated/networkx.algorithms.operators.binary.compose.html#networkx.algorithms.operators.binary.compose "networkx.algorithms.operators.binary.compose")
(G, H) | Compose graph G with H by combining nodes and edges into a single graph. | | [`union`](generated/networkx.algorithms.operators.binary.union.html#networkx.algorithms.operators.binary.union "networkx.algorithms.operators.binary.union")
(G, H\[, rename\]) | Combine graphs G and H. | | [`disjoint_union`](generated/networkx.algorithms.operators.binary.disjoint_union.html#networkx.algorithms.operators.binary.disjoint_union "networkx.algorithms.operators.binary.disjoint_union")
(G, H) | Combine graphs G and H. | | [`intersection`](generated/networkx.algorithms.operators.binary.intersection.html#networkx.algorithms.operators.binary.intersection "networkx.algorithms.operators.binary.intersection")
(G, H) | Returns a new graph that contains only the nodes and the edges that exist in both G and H. | | [`difference`](generated/networkx.algorithms.operators.binary.difference.html#networkx.algorithms.operators.binary.difference "networkx.algorithms.operators.binary.difference")
(G, H) | Returns a new graph that contains the edges that exist in G but not in H. | | [`symmetric_difference`](generated/networkx.algorithms.operators.binary.symmetric_difference.html#networkx.algorithms.operators.binary.symmetric_difference "networkx.algorithms.operators.binary.symmetric_difference")
(G, H) | Returns new graph with edges that exist in either G or H but not both. | | [`full_join`](generated/networkx.algorithms.operators.binary.full_join.html#networkx.algorithms.operators.binary.full_join "networkx.algorithms.operators.binary.full_join")
(G, H\[, rename\]) | Returns the full join of graphs G and H. | Operations on many graphs. | | | | --- | --- | | [`compose_all`](generated/networkx.algorithms.operators.all.compose_all.html#networkx.algorithms.operators.all.compose_all "networkx.algorithms.operators.all.compose_all")
(graphs) | Returns the composition of all graphs. | | [`union_all`](generated/networkx.algorithms.operators.all.union_all.html#networkx.algorithms.operators.all.union_all "networkx.algorithms.operators.all.union_all")
(graphs\[, rename\]) | Returns the union of all graphs. | | [`disjoint_union_all`](generated/networkx.algorithms.operators.all.disjoint_union_all.html#networkx.algorithms.operators.all.disjoint_union_all "networkx.algorithms.operators.all.disjoint_union_all")
(graphs) | Returns the disjoint union of all graphs. | | [`intersection_all`](generated/networkx.algorithms.operators.all.intersection_all.html#networkx.algorithms.operators.all.intersection_all "networkx.algorithms.operators.all.intersection_all")
(graphs) | Returns a new graph that contains only the nodes and the edges that exist in all graphs. | Graph products. | | | | --- | --- | | [`cartesian_product`](generated/networkx.algorithms.operators.product.cartesian_product.html#networkx.algorithms.operators.product.cartesian_product "networkx.algorithms.operators.product.cartesian_product")
(G, H) | Returns the Cartesian product of G and H. | | [`lexicographic_product`](generated/networkx.algorithms.operators.product.lexicographic_product.html#networkx.algorithms.operators.product.lexicographic_product "networkx.algorithms.operators.product.lexicographic_product")
(G, H) | Returns the lexicographic product of G and H. | | [`rooted_product`](generated/networkx.algorithms.operators.product.rooted_product.html#networkx.algorithms.operators.product.rooted_product "networkx.algorithms.operators.product.rooted_product")
(G, H, root) | Return the rooted product of graphs G and H rooted at root in H. | | [`strong_product`](generated/networkx.algorithms.operators.product.strong_product.html#networkx.algorithms.operators.product.strong_product "networkx.algorithms.operators.product.strong_product")
(G, H) | Returns the strong product of G and H. | | [`tensor_product`](generated/networkx.algorithms.operators.product.tensor_product.html#networkx.algorithms.operators.product.tensor_product "networkx.algorithms.operators.product.tensor_product")
(G, H) | Returns the tensor product of G and H. | | [`power`](generated/networkx.algorithms.operators.product.power.html#networkx.algorithms.operators.product.power "networkx.algorithms.operators.product.power")
(G, k) | Returns the specified power of a graph. | | [`corona_product`](generated/networkx.algorithms.operators.product.corona_product.html#networkx.algorithms.operators.product.corona_product "networkx.algorithms.operators.product.corona_product")
(G, H) | Returns the Corona product of G and H. | | [`modular_product`](generated/networkx.algorithms.operators.product.modular_product.html#networkx.algorithms.operators.product.modular_product "networkx.algorithms.operators.product.modular_product")
(G, H) | Returns the Modular product of G and H. | --- # non-randomness — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") non-randomness[#](#module-networkx.algorithms.non_randomness "Link to this heading") ===================================================================================== Computation of graph non-randomness | | | | --- | --- | | [`non_randomness`](generated/networkx.algorithms.non_randomness.non_randomness.html#networkx.algorithms.non_randomness.non_randomness "networkx.algorithms.non_randomness.non_randomness")
(G\[, k, weight\]) | Compute the non-randomness of graph G. | --- # Node Classification — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Node Classification[#](#module-networkx.algorithms.node_classification "Link to this heading") =============================================================================================== This module provides the functions for node classification problem. The functions in this module are not imported into the top level `networkx` namespace. You can access these functions by importing the [`networkx.algorithms.node_classification`](#module-networkx.algorithms.node_classification "networkx.algorithms.node_classification") modules, then accessing the functions as attributes of `node_classification`. For example: \>>> from networkx.algorithms import node\_classification \>>> G \= nx.path\_graph(4) \>>> G.edges() EdgeView(\[(0, 1), (1, 2), (2, 3)\]) \>>> G.nodes\[0\]\["label"\] \= "A" \>>> G.nodes\[3\]\["label"\] \= "B" \>>> node\_classification.harmonic\_function(G) \['A', 'A', 'B', 'B'\] References[#](#references "Link to this heading") -------------------------------------------------- Zhu, X., Ghahramani, Z., & Lafferty, J. (2003, August). Semi-supervised learning using gaussian fields and harmonic functions. In ICML (Vol. 3, pp. 912-919). | | | | --- | --- | | [`harmonic_function`](generated/networkx.algorithms.node_classification.harmonic_function.html#networkx.algorithms.node_classification.harmonic_function "networkx.algorithms.node_classification.harmonic_function")
(G\[, max\_iter, label\_name\]) | Node classification by Harmonic function | | [`local_and_global_consistency`](generated/networkx.algorithms.node_classification.local_and_global_consistency.html#networkx.algorithms.node_classification.local_and_global_consistency "networkx.algorithms.node_classification.local_and_global_consistency")
(G\[, alpha, ...\]) | Node classification by Local and Global Consistency | On this page --- # Planar Drawing — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Planar Drawing[#](#module-networkx.algorithms.planar_drawing "Link to this heading") ===================================================================================== | | | | --- | --- | | [`combinatorial_embedding_to_pos`](generated/networkx.algorithms.planar_drawing.combinatorial_embedding_to_pos.html#networkx.algorithms.planar_drawing.combinatorial_embedding_to_pos "networkx.algorithms.planar_drawing.combinatorial_embedding_to_pos")
(embedding\[, ...\]) | Assigns every node a (x, y) position based on the given embedding | --- # Planarity — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Planarity[#](#module-networkx.algorithms.planarity "Link to this heading") =========================================================================== | | | | --- | --- | | [`check_planarity`](generated/networkx.algorithms.planarity.check_planarity.html#networkx.algorithms.planarity.check_planarity "networkx.algorithms.planarity.check_planarity")
(G\[, counterexample\]) | Check if a graph is planar and return a counterexample or an embedding. | | [`is_planar`](generated/networkx.algorithms.planarity.is_planar.html#networkx.algorithms.planarity.is_planar "networkx.algorithms.planarity.is_planar")
(G) | Returns True if and only if `G` is planar. | | [`PlanarEmbedding`](generated/networkx.algorithms.planarity.PlanarEmbedding.html#networkx.algorithms.planarity.PlanarEmbedding "networkx.algorithms.planarity.PlanarEmbedding")
(\[incoming\_graph\_data\]) | Represents a planar graph with its planar embedding. | --- # Graph Polynomials — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Graph Polynomials[#](#module-networkx.algorithms.polynomials "Link to this heading") ===================================================================================== Provides algorithms supporting the computation of graph polynomials. Graph polynomials are polynomial-valued graph invariants that encode a wide variety of structural information. Examples include the Tutte polynomial, chromatic polynomial, characteristic polynomial, and matching polynomial. An extensive treatment is provided in [\[1\]](#r7556db9a3b5a-1) . For a simple example, the `charpoly` method can be used to compute the characteristic polynomial from the adjacency matrix of a graph. Consider the complete graph `K_4`: \>>> import sympy \>>> x \= sympy.Symbol("x") \>>> G \= nx.complete\_graph(4) \>>> A \= nx.to\_numpy\_array(G, dtype\=int) \>>> M \= sympy.SparseMatrix(A) \>>> M.charpoly(x).as\_expr() x\*\*4 - 6\*x\*\*2 - 8\*x - 3 \[[1](#id1)\ \] Y. Shi, M. Dehmer, X. Li, I. Gutman, “Graph Polynomials” | | | | --- | --- | | [`tutte_polynomial`](generated/networkx.algorithms.polynomials.tutte_polynomial.html#networkx.algorithms.polynomials.tutte_polynomial "networkx.algorithms.polynomials.tutte_polynomial")
(G) | Returns the Tutte polynomial of `G` | | [`chromatic_polynomial`](generated/networkx.algorithms.polynomials.chromatic_polynomial.html#networkx.algorithms.polynomials.chromatic_polynomial "networkx.algorithms.polynomials.chromatic_polynomial")
(G) | Returns the chromatic polynomial of `G` | --- # Regular — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Regular[#](#module-networkx.algorithms.regular "Link to this heading") ======================================================================= Functions for computing and verifying regular graphs. | | | | --- | --- | | [`is_regular`](generated/networkx.algorithms.regular.is_regular.html#networkx.algorithms.regular.is_regular "networkx.algorithms.regular.is_regular")
(G) | Determines whether the graph `G` is a regular graph. | | [`is_k_regular`](generated/networkx.algorithms.regular.is_k_regular.html#networkx.algorithms.regular.is_k_regular "networkx.algorithms.regular.is_k_regular")
(G, k) | Determines whether the graph `G` is a k-regular graph. | | [`k_factor`](generated/networkx.algorithms.regular.k_factor.html#networkx.algorithms.regular.k_factor "networkx.algorithms.regular.k_factor")
(G, k\[, matching\_weight\]) | Compute a k-factor of G | --- # Reciprocity — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Reciprocity[#](#module-networkx.algorithms.reciprocity "Link to this heading") =============================================================================== Algorithms to calculate reciprocity in a directed graph. | | | | --- | --- | | [`reciprocity`](generated/networkx.algorithms.reciprocity.reciprocity.html#networkx.algorithms.reciprocity.reciprocity "networkx.algorithms.reciprocity.reciprocity")
(G\[, nodes\]) | Compute the reciprocity in a directed graph. | | [`overall_reciprocity`](generated/networkx.algorithms.reciprocity.overall_reciprocity.html#networkx.algorithms.reciprocity.overall_reciprocity "networkx.algorithms.reciprocity.overall_reciprocity")
(G) | Compute the reciprocity for the whole graph. | --- # Rich Club — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Rich Club[#](#module-networkx.algorithms.richclub "Link to this heading") ========================================================================== Functions for computing rich-club coefficients. | | | | --- | --- | | [`rich_club_coefficient`](generated/networkx.algorithms.richclub.rich_club_coefficient.html#networkx.algorithms.richclub.rich_club_coefficient "networkx.algorithms.richclub.rich_club_coefficient")
(G\[, normalized, Q, seed\]) | Returns the rich-club coefficient of the graph `G`. | --- # Shortest Paths — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Shortest Paths[#](#module-networkx.algorithms.shortest_paths.generic "Link to this heading") ============================================================================================= Compute the shortest paths and path lengths between nodes in the graph. These algorithms work with undirected and directed graphs. | | | | --- | --- | | [`shortest_path`](generated/networkx.algorithms.shortest_paths.generic.shortest_path.html#networkx.algorithms.shortest_paths.generic.shortest_path "networkx.algorithms.shortest_paths.generic.shortest_path")
(G\[, source, target, weight, ...\]) | Compute shortest paths in the graph. | | [`all_shortest_paths`](generated/networkx.algorithms.shortest_paths.generic.all_shortest_paths.html#networkx.algorithms.shortest_paths.generic.all_shortest_paths "networkx.algorithms.shortest_paths.generic.all_shortest_paths")
(G, source, target\[, ...\]) | Compute all shortest simple paths in the graph. | | [`all_pairs_all_shortest_paths`](generated/networkx.algorithms.shortest_paths.generic.all_pairs_all_shortest_paths.html#networkx.algorithms.shortest_paths.generic.all_pairs_all_shortest_paths "networkx.algorithms.shortest_paths.generic.all_pairs_all_shortest_paths")
(G\[, weight, method\]) | Compute all shortest paths between all nodes. | | [`single_source_all_shortest_paths`](generated/networkx.algorithms.shortest_paths.generic.single_source_all_shortest_paths.html#networkx.algorithms.shortest_paths.generic.single_source_all_shortest_paths "networkx.algorithms.shortest_paths.generic.single_source_all_shortest_paths")
(G, source) | Compute all shortest simple paths from the given source in the graph. | | [`shortest_path_length`](generated/networkx.algorithms.shortest_paths.generic.shortest_path_length.html#networkx.algorithms.shortest_paths.generic.shortest_path_length "networkx.algorithms.shortest_paths.generic.shortest_path_length")
(G\[, source, target, ...\]) | Compute shortest path lengths in the graph. | | [`average_shortest_path_length`](generated/networkx.algorithms.shortest_paths.generic.average_shortest_path_length.html#networkx.algorithms.shortest_paths.generic.average_shortest_path_length "networkx.algorithms.shortest_paths.generic.average_shortest_path_length")
(G\[, weight, method\]) | Returns the average shortest path length. | | [`has_path`](generated/networkx.algorithms.shortest_paths.generic.has_path.html#networkx.algorithms.shortest_paths.generic.has_path "networkx.algorithms.shortest_paths.generic.has_path")
(G, source, target) | Returns _True_ if _G_ has a path from _source_ to _target_. | Advanced Interface[#](#module-networkx.algorithms.shortest_paths.unweighted "Link to this heading") ---------------------------------------------------------------------------------------------------- Shortest path algorithms for unweighted graphs. | | | | --- | --- | | [`single_source_shortest_path`](generated/networkx.algorithms.shortest_paths.unweighted.single_source_shortest_path.html#networkx.algorithms.shortest_paths.unweighted.single_source_shortest_path "networkx.algorithms.shortest_paths.unweighted.single_source_shortest_path")
(G, source\[, cutoff\]) | Compute shortest path between source and all other nodes reachable from source. | | [`single_source_shortest_path_length`](generated/networkx.algorithms.shortest_paths.unweighted.single_source_shortest_path_length.html#networkx.algorithms.shortest_paths.unweighted.single_source_shortest_path_length "networkx.algorithms.shortest_paths.unweighted.single_source_shortest_path_length")
(G, source) | Compute the shortest path lengths from source to all reachable nodes. | | [`single_target_shortest_path`](generated/networkx.algorithms.shortest_paths.unweighted.single_target_shortest_path.html#networkx.algorithms.shortest_paths.unweighted.single_target_shortest_path "networkx.algorithms.shortest_paths.unweighted.single_target_shortest_path")
(G, target\[, cutoff\]) | Compute shortest path to target from all nodes that reach target. | | [`single_target_shortest_path_length`](generated/networkx.algorithms.shortest_paths.unweighted.single_target_shortest_path_length.html#networkx.algorithms.shortest_paths.unweighted.single_target_shortest_path_length "networkx.algorithms.shortest_paths.unweighted.single_target_shortest_path_length")
(G, target) | Compute the shortest path lengths to target from all reachable nodes. | | [`bidirectional_shortest_path`](generated/networkx.algorithms.shortest_paths.unweighted.bidirectional_shortest_path.html#networkx.algorithms.shortest_paths.unweighted.bidirectional_shortest_path "networkx.algorithms.shortest_paths.unweighted.bidirectional_shortest_path")
(G, source, target) | Returns a list of nodes in a shortest path between source and target. | | [`all_pairs_shortest_path`](generated/networkx.algorithms.shortest_paths.unweighted.all_pairs_shortest_path.html#networkx.algorithms.shortest_paths.unweighted.all_pairs_shortest_path "networkx.algorithms.shortest_paths.unweighted.all_pairs_shortest_path")
(G\[, cutoff\]) | Compute shortest paths between all nodes. | | [`all_pairs_shortest_path_length`](generated/networkx.algorithms.shortest_paths.unweighted.all_pairs_shortest_path_length.html#networkx.algorithms.shortest_paths.unweighted.all_pairs_shortest_path_length "networkx.algorithms.shortest_paths.unweighted.all_pairs_shortest_path_length")
(G\[, cutoff\]) | Computes the shortest path lengths between all nodes in `G`. | | [`predecessor`](generated/networkx.algorithms.shortest_paths.unweighted.predecessor.html#networkx.algorithms.shortest_paths.unweighted.predecessor "networkx.algorithms.shortest_paths.unweighted.predecessor")
(G, source\[, target, cutoff, ...\]) | Returns dict of predecessors for the path from source to all nodes in G. | Shortest path algorithms for weighted graphs. | | | | --- | --- | | [`dijkstra_predecessor_and_distance`](generated/networkx.algorithms.shortest_paths.weighted.dijkstra_predecessor_and_distance.html#networkx.algorithms.shortest_paths.weighted.dijkstra_predecessor_and_distance "networkx.algorithms.shortest_paths.weighted.dijkstra_predecessor_and_distance")
(G, source) | Compute weighted shortest path length and predecessors. | | [`dijkstra_path`](generated/networkx.algorithms.shortest_paths.weighted.dijkstra_path.html#networkx.algorithms.shortest_paths.weighted.dijkstra_path "networkx.algorithms.shortest_paths.weighted.dijkstra_path")
(G, source, target\[, weight\]) | Returns the shortest weighted path from source to target in G. | | [`dijkstra_path_length`](generated/networkx.algorithms.shortest_paths.weighted.dijkstra_path_length.html#networkx.algorithms.shortest_paths.weighted.dijkstra_path_length "networkx.algorithms.shortest_paths.weighted.dijkstra_path_length")
(G, source, target\[, weight\]) | Returns the shortest weighted path length in G from source to target. | | [`single_source_dijkstra`](generated/networkx.algorithms.shortest_paths.weighted.single_source_dijkstra.html#networkx.algorithms.shortest_paths.weighted.single_source_dijkstra "networkx.algorithms.shortest_paths.weighted.single_source_dijkstra")
(G, source\[, target, ...\]) | Find shortest weighted paths and lengths from a source node. | | [`single_source_dijkstra_path`](generated/networkx.algorithms.shortest_paths.weighted.single_source_dijkstra_path.html#networkx.algorithms.shortest_paths.weighted.single_source_dijkstra_path "networkx.algorithms.shortest_paths.weighted.single_source_dijkstra_path")
(G, source\[, ...\]) | Find shortest weighted paths in G from a source node. | | [`single_source_dijkstra_path_length`](generated/networkx.algorithms.shortest_paths.weighted.single_source_dijkstra_path_length.html#networkx.algorithms.shortest_paths.weighted.single_source_dijkstra_path_length "networkx.algorithms.shortest_paths.weighted.single_source_dijkstra_path_length")
(G, source) | Find shortest weighted path lengths in G from a source node. | | [`multi_source_dijkstra`](generated/networkx.algorithms.shortest_paths.weighted.multi_source_dijkstra.html#networkx.algorithms.shortest_paths.weighted.multi_source_dijkstra "networkx.algorithms.shortest_paths.weighted.multi_source_dijkstra")
(G, sources\[, target, ...\]) | Find shortest weighted paths and lengths from a given set of source nodes. | | [`multi_source_dijkstra_path`](generated/networkx.algorithms.shortest_paths.weighted.multi_source_dijkstra_path.html#networkx.algorithms.shortest_paths.weighted.multi_source_dijkstra_path "networkx.algorithms.shortest_paths.weighted.multi_source_dijkstra_path")
(G, sources\[, ...\]) | Find shortest weighted paths in G from a given set of source nodes. | | [`multi_source_dijkstra_path_length`](generated/networkx.algorithms.shortest_paths.weighted.multi_source_dijkstra_path_length.html#networkx.algorithms.shortest_paths.weighted.multi_source_dijkstra_path_length "networkx.algorithms.shortest_paths.weighted.multi_source_dijkstra_path_length")
(G, sources) | Find shortest weighted path lengths in G from a given set of source nodes. | | [`all_pairs_dijkstra`](generated/networkx.algorithms.shortest_paths.weighted.all_pairs_dijkstra.html#networkx.algorithms.shortest_paths.weighted.all_pairs_dijkstra "networkx.algorithms.shortest_paths.weighted.all_pairs_dijkstra")
(G\[, cutoff, weight\]) | Find shortest weighted paths and lengths between all nodes. | | [`all_pairs_dijkstra_path`](generated/networkx.algorithms.shortest_paths.weighted.all_pairs_dijkstra_path.html#networkx.algorithms.shortest_paths.weighted.all_pairs_dijkstra_path "networkx.algorithms.shortest_paths.weighted.all_pairs_dijkstra_path")
(G\[, cutoff, weight\]) | Compute shortest paths between all nodes in a weighted graph. | | [`all_pairs_dijkstra_path_length`](generated/networkx.algorithms.shortest_paths.weighted.all_pairs_dijkstra_path_length.html#networkx.algorithms.shortest_paths.weighted.all_pairs_dijkstra_path_length "networkx.algorithms.shortest_paths.weighted.all_pairs_dijkstra_path_length")
(G\[, cutoff, ...\]) | Compute shortest path lengths between all nodes in a weighted graph. | | [`bidirectional_dijkstra`](generated/networkx.algorithms.shortest_paths.weighted.bidirectional_dijkstra.html#networkx.algorithms.shortest_paths.weighted.bidirectional_dijkstra "networkx.algorithms.shortest_paths.weighted.bidirectional_dijkstra")
(G, source, target\[, ...\]) | Dijkstra's algorithm for shortest paths using bidirectional search. | | [`bellman_ford_path`](generated/networkx.algorithms.shortest_paths.weighted.bellman_ford_path.html#networkx.algorithms.shortest_paths.weighted.bellman_ford_path "networkx.algorithms.shortest_paths.weighted.bellman_ford_path")
(G, source, target\[, weight\]) | Returns the shortest path from source to target in a weighted graph G. | | [`bellman_ford_path_length`](generated/networkx.algorithms.shortest_paths.weighted.bellman_ford_path_length.html#networkx.algorithms.shortest_paths.weighted.bellman_ford_path_length "networkx.algorithms.shortest_paths.weighted.bellman_ford_path_length")
(G, source, target) | Returns the shortest path length from source to target in a weighted graph. | | [`single_source_bellman_ford`](generated/networkx.algorithms.shortest_paths.weighted.single_source_bellman_ford.html#networkx.algorithms.shortest_paths.weighted.single_source_bellman_ford "networkx.algorithms.shortest_paths.weighted.single_source_bellman_ford")
(G, source\[, ...\]) | Compute shortest paths and lengths in a weighted graph G. | | [`single_source_bellman_ford_path`](generated/networkx.algorithms.shortest_paths.weighted.single_source_bellman_ford_path.html#networkx.algorithms.shortest_paths.weighted.single_source_bellman_ford_path "networkx.algorithms.shortest_paths.weighted.single_source_bellman_ford_path")
(G, source\[, ...\]) | Compute shortest path between source and all other reachable nodes for a weighted graph. | | [`single_source_bellman_ford_path_length`](generated/networkx.algorithms.shortest_paths.weighted.single_source_bellman_ford_path_length.html#networkx.algorithms.shortest_paths.weighted.single_source_bellman_ford_path_length "networkx.algorithms.shortest_paths.weighted.single_source_bellman_ford_path_length")
(G, source) | Compute the shortest path length between source and all other reachable nodes for a weighted graph. | | [`all_pairs_bellman_ford_path`](generated/networkx.algorithms.shortest_paths.weighted.all_pairs_bellman_ford_path.html#networkx.algorithms.shortest_paths.weighted.all_pairs_bellman_ford_path "networkx.algorithms.shortest_paths.weighted.all_pairs_bellman_ford_path")
(G\[, weight\]) | Compute shortest paths between all nodes in a weighted graph. | | [`all_pairs_bellman_ford_path_length`](generated/networkx.algorithms.shortest_paths.weighted.all_pairs_bellman_ford_path_length.html#networkx.algorithms.shortest_paths.weighted.all_pairs_bellman_ford_path_length "networkx.algorithms.shortest_paths.weighted.all_pairs_bellman_ford_path_length")
(G\[, weight\]) | Compute shortest path lengths between all nodes in a weighted graph. | | [`bellman_ford_predecessor_and_distance`](generated/networkx.algorithms.shortest_paths.weighted.bellman_ford_predecessor_and_distance.html#networkx.algorithms.shortest_paths.weighted.bellman_ford_predecessor_and_distance "networkx.algorithms.shortest_paths.weighted.bellman_ford_predecessor_and_distance")
(G, source) | Compute shortest path lengths and predecessors on shortest paths in weighted graphs. | | [`negative_edge_cycle`](generated/networkx.algorithms.shortest_paths.weighted.negative_edge_cycle.html#networkx.algorithms.shortest_paths.weighted.negative_edge_cycle "networkx.algorithms.shortest_paths.weighted.negative_edge_cycle")
(G\[, weight, heuristic\]) | Returns True if there exists a negative edge cycle anywhere in G. | | [`find_negative_cycle`](generated/networkx.algorithms.shortest_paths.weighted.find_negative_cycle.html#networkx.algorithms.shortest_paths.weighted.find_negative_cycle "networkx.algorithms.shortest_paths.weighted.find_negative_cycle")
(G, source\[, weight\]) | Returns a cycle with negative total weight if it exists. | | [`goldberg_radzik`](generated/networkx.algorithms.shortest_paths.weighted.goldberg_radzik.html#networkx.algorithms.shortest_paths.weighted.goldberg_radzik "networkx.algorithms.shortest_paths.weighted.goldberg_radzik")
(G, source\[, weight\]) | Compute shortest path lengths and predecessors on shortest paths in weighted graphs. | | [`johnson`](generated/networkx.algorithms.shortest_paths.weighted.johnson.html#networkx.algorithms.shortest_paths.weighted.johnson "networkx.algorithms.shortest_paths.weighted.johnson")
(G\[, weight\]) | Uses Johnson's Algorithm to compute shortest paths. | Dense Graphs[#](#module-networkx.algorithms.shortest_paths.dense "Link to this heading") ----------------------------------------------------------------------------------------- Floyd-Warshall algorithm for shortest paths. | | | | --- | --- | | [`floyd_warshall`](generated/networkx.algorithms.shortest_paths.dense.floyd_warshall.html#networkx.algorithms.shortest_paths.dense.floyd_warshall "networkx.algorithms.shortest_paths.dense.floyd_warshall")
(G\[, weight\]) | Find all-pairs shortest path lengths using Floyd's algorithm. | | [`floyd_warshall_predecessor_and_distance`](generated/networkx.algorithms.shortest_paths.dense.floyd_warshall_predecessor_and_distance.html#networkx.algorithms.shortest_paths.dense.floyd_warshall_predecessor_and_distance "networkx.algorithms.shortest_paths.dense.floyd_warshall_predecessor_and_distance")
(G\[, ...\]) | Find all-pairs shortest path lengths using Floyd's algorithm. | | [`floyd_warshall_numpy`](generated/networkx.algorithms.shortest_paths.dense.floyd_warshall_numpy.html#networkx.algorithms.shortest_paths.dense.floyd_warshall_numpy "networkx.algorithms.shortest_paths.dense.floyd_warshall_numpy")
(G\[, nodelist, weight\]) | Find all-pairs shortest path lengths using Floyd's algorithm. | | [`reconstruct_path`](generated/networkx.algorithms.shortest_paths.dense.reconstruct_path.html#networkx.algorithms.shortest_paths.dense.reconstruct_path "networkx.algorithms.shortest_paths.dense.reconstruct_path")
(source, target, predecessors) | Reconstruct a path from source to target using the predecessors dict as returned by floyd\_warshall\_predecessor\_and\_distance | A\* Algorithm[#](#module-networkx.algorithms.shortest_paths.astar "Link to this heading") ------------------------------------------------------------------------------------------ Shortest paths and path lengths using the A\* (“A star”) algorithm. | | | | --- | --- | | [`astar_path`](generated/networkx.algorithms.shortest_paths.astar.astar_path.html#networkx.algorithms.shortest_paths.astar.astar_path "networkx.algorithms.shortest_paths.astar.astar_path")
(G, source, target\[, heuristic, ...\]) | Returns a list of nodes in a shortest path between source and target using the A\* ("A-star") algorithm. | | [`astar_path_length`](generated/networkx.algorithms.shortest_paths.astar.astar_path_length.html#networkx.algorithms.shortest_paths.astar.astar_path_length "networkx.algorithms.shortest_paths.astar.astar_path_length")
(G, source, target\[, ...\]) | Returns the length of the shortest path between source and target using the A\* ("A-star") algorithm. | On this page --- # Similarity Measures — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Similarity Measures[#](#module-networkx.algorithms.similarity "Link to this heading") ====================================================================================== Functions measuring similarity using graph edit distance. The graph edit distance is the number of edge/node changes needed to make two graphs isomorphic. The default algorithm/implementation is sub-optimal for some graphs. The problem of finding the exact Graph Edit Distance (GED) is NP-hard so it is often slow. If the simple interface [`graph_edit_distance`](generated/networkx.algorithms.similarity.graph_edit_distance.html#networkx.algorithms.similarity.graph_edit_distance "networkx.algorithms.similarity.graph_edit_distance") takes too long for your graph, try [`optimize_graph_edit_distance`](generated/networkx.algorithms.similarity.optimize_graph_edit_distance.html#networkx.algorithms.similarity.optimize_graph_edit_distance "networkx.algorithms.similarity.optimize_graph_edit_distance") and/or [`optimize_edit_paths`](generated/networkx.algorithms.similarity.optimize_edit_paths.html#networkx.algorithms.similarity.optimize_edit_paths "networkx.algorithms.similarity.optimize_edit_paths") . At the same time, I encourage capable people to investigate alternative GED algorithms, in order to improve the choices available. | | | | --- | --- | | [`graph_edit_distance`](generated/networkx.algorithms.similarity.graph_edit_distance.html#networkx.algorithms.similarity.graph_edit_distance "networkx.algorithms.similarity.graph_edit_distance")
(G1, G2\[, node\_match, ...\]) | Returns GED (graph edit distance) between graphs G1 and G2. | | [`optimal_edit_paths`](generated/networkx.algorithms.similarity.optimal_edit_paths.html#networkx.algorithms.similarity.optimal_edit_paths "networkx.algorithms.similarity.optimal_edit_paths")
(G1, G2\[, node\_match, ...\]) | Returns all minimum-cost edit paths transforming G1 to G2. | | [`optimize_graph_edit_distance`](generated/networkx.algorithms.similarity.optimize_graph_edit_distance.html#networkx.algorithms.similarity.optimize_graph_edit_distance "networkx.algorithms.similarity.optimize_graph_edit_distance")
(G1, G2\[, ...\]) | Returns consecutive approximations of GED (graph edit distance) between graphs G1 and G2. | | [`optimize_edit_paths`](generated/networkx.algorithms.similarity.optimize_edit_paths.html#networkx.algorithms.similarity.optimize_edit_paths "networkx.algorithms.similarity.optimize_edit_paths")
(G1, G2\[, node\_match, ...\]) | GED (graph edit distance) calculation: advanced interface. | | [`simrank_similarity`](generated/networkx.algorithms.similarity.simrank_similarity.html#networkx.algorithms.similarity.simrank_similarity "networkx.algorithms.similarity.simrank_similarity")
(G\[, source, target, ...\]) | Returns the SimRank similarity of nodes in the graph `G`. | | [`panther_similarity`](generated/networkx.algorithms.similarity.panther_similarity.html#networkx.algorithms.similarity.panther_similarity "networkx.algorithms.similarity.panther_similarity")
(G, source\[, k, ...\]) | Returns the Panther similarity of nodes in the graph `G` to node `v`. | | [`generate_random_paths`](generated/networkx.algorithms.similarity.generate_random_paths.html#networkx.algorithms.similarity.generate_random_paths "networkx.algorithms.similarity.generate_random_paths")
(G, sample\_size\[, ...\]) | Randomly generate `sample_size` paths of length `path_length`. | --- # Simple Paths — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Simple Paths[#](#module-networkx.algorithms.simple_paths "Link to this heading") ================================================================================= | | | | --- | --- | | [`all_simple_paths`](generated/networkx.algorithms.simple_paths.all_simple_paths.html#networkx.algorithms.simple_paths.all_simple_paths "networkx.algorithms.simple_paths.all_simple_paths")
(G, source, target\[, cutoff\]) | Generate all simple paths in the graph G from source to target. | | [`all_simple_edge_paths`](generated/networkx.algorithms.simple_paths.all_simple_edge_paths.html#networkx.algorithms.simple_paths.all_simple_edge_paths "networkx.algorithms.simple_paths.all_simple_edge_paths")
(G, source, target\[, ...\]) | Generate lists of edges for all simple paths in G from source to target. | | [`is_simple_path`](generated/networkx.algorithms.simple_paths.is_simple_path.html#networkx.algorithms.simple_paths.is_simple_path "networkx.algorithms.simple_paths.is_simple_path")
(G, nodes) | Returns True if and only if `nodes` form a simple path in `G`. | | [`shortest_simple_paths`](generated/networkx.algorithms.simple_paths.shortest_simple_paths.html#networkx.algorithms.simple_paths.shortest_simple_paths "networkx.algorithms.simple_paths.shortest_simple_paths")
(G, source, target\[, ...\]) | Generate all simple paths in the graph G from source to target, | --- # Small-world — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Small-world[#](#module-networkx.algorithms.smallworld "Link to this heading") ============================================================================== Functions for estimating the small-world-ness of graphs. A small world network is characterized by a small average shortest path length, and a large clustering coefficient. Small-worldness is commonly measured with the coefficient sigma or omega. Both coefficients compare the average clustering coefficient and shortest path length of a given graph against the same quantities for an equivalent random or lattice graph. For more information, see the Wikipedia article on small-world network [\[1\]](#r68ac8e14dfc9-1) . \[[1](#id1)\ \] Small-world network:: [https://en.wikipedia.org/wiki/Small-world\_network](https://en.wikipedia.org/wiki/Small-world_network) | | | | --- | --- | | [`random_reference`](generated/networkx.algorithms.smallworld.random_reference.html#networkx.algorithms.smallworld.random_reference "networkx.algorithms.smallworld.random_reference")
(G\[, niter, connectivity, seed\]) | Compute a random graph by swapping edges of a given graph. | | [`lattice_reference`](generated/networkx.algorithms.smallworld.lattice_reference.html#networkx.algorithms.smallworld.lattice_reference "networkx.algorithms.smallworld.lattice_reference")
(G\[, niter, D, ...\]) | Latticize the given graph by swapping edges. | | [`sigma`](generated/networkx.algorithms.smallworld.sigma.html#networkx.algorithms.smallworld.sigma "networkx.algorithms.smallworld.sigma")
(G\[, niter, nrand, seed\]) | Returns the small-world coefficient (sigma) of the given graph. | | [`omega`](generated/networkx.algorithms.smallworld.omega.html#networkx.algorithms.smallworld.omega "networkx.algorithms.smallworld.omega")
(G\[, niter, nrand, seed\]) | Returns the small-world coefficient (omega) of a graph | --- # s metric — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") s metric[#](#module-networkx.algorithms.smetric "Link to this heading") ======================================================================== | | | | --- | --- | | [`s_metric`](generated/networkx.algorithms.smetric.s_metric.html#networkx.algorithms.smetric.s_metric "networkx.algorithms.smetric.s_metric")
(G) | Returns the s-metric [\[R4ac31df7a658-1\]](generated/networkx.algorithms.smetric.s_metric.html#r4ac31df7a658-1)
of graph. | --- # Sparsifiers — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Sparsifiers[#](#module-networkx.algorithms.sparsifiers "Link to this heading") =============================================================================== Functions for computing sparsifiers of graphs. | | | | --- | --- | | [`spanner`](generated/networkx.algorithms.sparsifiers.spanner.html#networkx.algorithms.sparsifiers.spanner "networkx.algorithms.sparsifiers.spanner")
(G, stretch\[, weight, seed\]) | Returns a spanner of the given graph with the given stretch. | --- # Summarization — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Summarization[#](#module-networkx.algorithms.summarization "Link to this heading") =================================================================================== Graph summarization finds smaller representations of graphs resulting in faster runtime of algorithms, reduced storage needs, and noise reduction. Summarization has applications in areas such as visualization, pattern mining, clustering and community detection, and more. Core graph summarization techniques are grouping/aggregation, bit-compression, simplification/sparsification, and influence based. Graph summarization algorithms often produce either summary graphs in the form of supergraphs or sparsified graphs, or a list of independent structures. Supergraphs are the most common product, which consist of supernodes and original nodes and are connected by edges and superedges, which represent aggregate edges between nodes and supernodes. Grouping/aggregation based techniques compress graphs by representing close/connected nodes and edges in a graph by a single node/edge in a supergraph. Nodes can be grouped together into supernodes based on their structural similarities or proximity within a graph to reduce the total number of nodes in a graph. Edge-grouping techniques group edges into lossy/lossless nodes called compressor or virtual nodes to reduce the total number of edges in a graph. Edge-grouping techniques can be lossless, meaning that they can be used to re-create the original graph, or techniques can be lossy, requiring less space to store the summary graph, but at the expense of lower reconstruction accuracy of the original graph. Bit-compression techniques minimize the amount of information needed to describe the original graph, while revealing structural patterns in the original graph. The two-part minimum description length (MDL) is often used to represent the model and the original graph in terms of the model. A key difference between graph compression and graph summarization is that graph summarization focuses on finding structural patterns within the original graph, whereas graph compression focuses on compressions the original graph to be as small as possible. **NOTE**: Some bit-compression methods exist solely to compress a graph without creating a summary graph or finding comprehensible structural patterns. Simplification/Sparsification techniques attempt to create a sparse representation of a graph by removing unimportant nodes and edges from the graph. Sparsified graphs differ from supergraphs created by grouping/aggregation by only containing a subset of the original nodes and edges of the original graph. Influence based techniques aim to find a high-level description of influence propagation in a large graph. These methods are scarce and have been mostly applied to social graphs. _dedensification_ is a grouping/aggregation based technique to compress the neighborhoods around high-degree nodes in unweighted graphs by adding compressor nodes that summarize multiple edges of the same type to high-degree nodes (nodes with a degree greater than a given threshold). Dedensification was developed for the purpose of increasing performance of query processing around high-degree nodes in graph databases and enables direct operations on the compressed graph. The structural patterns surrounding high-degree nodes in the original is preserved while using fewer edges and adding a small number of compressor nodes. The degree of nodes present in the original graph is also preserved. The current implementation of dedensification supports graphs with one edge type. For more information on graph summarization, see [Graph Summarization Methods and Applications: A Survey](https://dl.acm.org/doi/abs/10.1145/3186727) | | | | --- | --- | | [`dedensify`](generated/networkx.algorithms.summarization.dedensify.html#networkx.algorithms.summarization.dedensify "networkx.algorithms.summarization.dedensify")
(G, threshold\[, prefix, copy\]) | Compresses neighborhoods around high-degree nodes | | [`snap_aggregation`](generated/networkx.algorithms.summarization.snap_aggregation.html#networkx.algorithms.summarization.snap_aggregation "networkx.algorithms.summarization.snap_aggregation")
(G, node\_attributes\[, ...\]) | Creates a summary graph based on attributes and connectivity. | --- # Structural holes — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Structural holes[#](#module-networkx.algorithms.structuralholes "Link to this heading") ======================================================================================== Functions for computing measures of structural holes. | | | | --- | --- | | [`constraint`](generated/networkx.algorithms.structuralholes.constraint.html#networkx.algorithms.structuralholes.constraint "networkx.algorithms.structuralholes.constraint")
(G\[, nodes, weight\]) | Returns the constraint on all nodes in the graph `G`. | | [`effective_size`](generated/networkx.algorithms.structuralholes.effective_size.html#networkx.algorithms.structuralholes.effective_size "networkx.algorithms.structuralholes.effective_size")
(G\[, nodes, weight\]) | Returns the effective size of all nodes in the graph `G`. | | [`local_constraint`](generated/networkx.algorithms.structuralholes.local_constraint.html#networkx.algorithms.structuralholes.local_constraint "networkx.algorithms.structuralholes.local_constraint")
(G, u, v\[, weight\]) | Returns the local constraint on the node `u` with respect to the node `v` in the graph `G`. | --- # Swap — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Swap[#](#module-networkx.algorithms.swap "Link to this heading") ================================================================= Swap edges in a graph. | | | | --- | --- | | [`double_edge_swap`](generated/networkx.algorithms.swap.double_edge_swap.html#networkx.algorithms.swap.double_edge_swap "networkx.algorithms.swap.double_edge_swap")
(G\[, nswap, max\_tries, seed\]) | Swap two edges in the graph while keeping the node degrees fixed. | | [`directed_edge_swap`](generated/networkx.algorithms.swap.directed_edge_swap.html#networkx.algorithms.swap.directed_edge_swap "networkx.algorithms.swap.directed_edge_swap")
(G, \*\[, nswap, max\_tries, ...\]) | Swap three edges in a directed graph while keeping the node degrees fixed. | | [`connected_double_edge_swap`](generated/networkx.algorithms.swap.connected_double_edge_swap.html#networkx.algorithms.swap.connected_double_edge_swap "networkx.algorithms.swap.connected_double_edge_swap")
(G\[, nswap, ...\]) | Attempts the specified number of double-edge swaps in the graph `G`. | --- # Time dependent — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Time dependent[#](#module-networkx.algorithms.time_dependent "Link to this heading") ===================================================================================== Time dependent algorithms. | | | | --- | --- | | [`cd_index`](generated/networkx.algorithms.time_dependent.cd_index.html#networkx.algorithms.time_dependent.cd_index "networkx.algorithms.time_dependent.cd_index")
(G, node, time\_delta, \*\[, time, weight\]) | Compute the CD index for `node` within the graph `G`. | --- # Threshold Graphs — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Threshold Graphs[#](#module-networkx.algorithms.threshold "Link to this heading") ================================================================================== Threshold Graphs - Creation, manipulation and identification. | | | | --- | --- | | [`find_threshold_graph`](generated/networkx.algorithms.threshold.find_threshold_graph.html#networkx.algorithms.threshold.find_threshold_graph "networkx.algorithms.threshold.find_threshold_graph")
(G\[, create\_using\]) | Returns a threshold subgraph that is close to largest in `G`. | | [`is_threshold_graph`](generated/networkx.algorithms.threshold.is_threshold_graph.html#networkx.algorithms.threshold.is_threshold_graph "networkx.algorithms.threshold.is_threshold_graph")
(G) | Returns [`True`](https://docs.python.org/3/library/constants.html#True "(in Python v3.13)")
if `G` is a threshold graph. | --- # Tournament — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Tournament[#](#module-networkx.algorithms.tournament "Link to this heading") ============================================================================= Functions concerning tournament graphs. A [tournament graph](https://en.wikipedia.org/wiki/Tournament_%28graph_theory%29) is a complete oriented graph. In other words, it is a directed graph in which there is exactly one directed edge joining each pair of distinct nodes. For each function in this module that accepts a graph as input, you must provide a tournament graph. The responsibility is on the caller to ensure that the graph is a tournament graph: \>>> G \= nx.DiGraph(\[(0, 1), (1, 2), (2, 0)\]) \>>> nx.is\_tournament(G) True To access the functions in this module, you must access them through the `networkx.tournament` module: \>>> nx.tournament.is\_reachable(G, 0, 1) True | | | | --- | --- | | [`hamiltonian_path`](generated/networkx.algorithms.tournament.hamiltonian_path.html#networkx.algorithms.tournament.hamiltonian_path "networkx.algorithms.tournament.hamiltonian_path")
(G) | Returns a Hamiltonian path in the given tournament graph. | | [`is_reachable`](generated/networkx.algorithms.tournament.is_reachable.html#networkx.algorithms.tournament.is_reachable "networkx.algorithms.tournament.is_reachable")
(G, s, t) | Decides whether there is a path from `s` to `t` in the tournament. | | [`is_strongly_connected`](generated/networkx.algorithms.tournament.is_strongly_connected.html#networkx.algorithms.tournament.is_strongly_connected "networkx.algorithms.tournament.is_strongly_connected")
(G) | Decides whether the given tournament is strongly connected. | | [`is_tournament`](generated/networkx.algorithms.tournament.is_tournament.html#networkx.algorithms.tournament.is_tournament "networkx.algorithms.tournament.is_tournament")
(G) | Returns True if and only if `G` is a tournament. | | [`random_tournament`](generated/networkx.algorithms.tournament.random_tournament.html#networkx.algorithms.tournament.random_tournament "networkx.algorithms.tournament.random_tournament")
(n\[, seed\]) | Returns a random tournament graph on `n` nodes. | | [`score_sequence`](generated/networkx.algorithms.tournament.score_sequence.html#networkx.algorithms.tournament.score_sequence "networkx.algorithms.tournament.score_sequence")
(G) | Returns the score sequence for the given tournament graph. | --- # Traversal — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Traversal[#](#traversal "Link to this heading") ================================================ Depth First Search[#](#module-networkx.algorithms.traversal.depth_first_search "Link to this heading") ------------------------------------------------------------------------------------------------------- Basic algorithms for depth-first searching the nodes of a graph. | | | | --- | --- | | [`dfs_edges`](generated/networkx.algorithms.traversal.depth_first_search.dfs_edges.html#networkx.algorithms.traversal.depth_first_search.dfs_edges "networkx.algorithms.traversal.depth_first_search.dfs_edges")
(G\[, source, depth\_limit, ...\]) | Iterate over edges in a depth-first-search (DFS). | | [`dfs_tree`](generated/networkx.algorithms.traversal.depth_first_search.dfs_tree.html#networkx.algorithms.traversal.depth_first_search.dfs_tree "networkx.algorithms.traversal.depth_first_search.dfs_tree")
(G\[, source, depth\_limit, ...\]) | Returns oriented tree constructed from a depth-first-search from source. | | [`dfs_predecessors`](generated/networkx.algorithms.traversal.depth_first_search.dfs_predecessors.html#networkx.algorithms.traversal.depth_first_search.dfs_predecessors "networkx.algorithms.traversal.depth_first_search.dfs_predecessors")
(G\[, source, depth\_limit, ...\]) | Returns dictionary of predecessors in depth-first-search from source. | | [`dfs_successors`](generated/networkx.algorithms.traversal.depth_first_search.dfs_successors.html#networkx.algorithms.traversal.depth_first_search.dfs_successors "networkx.algorithms.traversal.depth_first_search.dfs_successors")
(G\[, source, depth\_limit, ...\]) | Returns dictionary of successors in depth-first-search from source. | | [`dfs_preorder_nodes`](generated/networkx.algorithms.traversal.depth_first_search.dfs_preorder_nodes.html#networkx.algorithms.traversal.depth_first_search.dfs_preorder_nodes "networkx.algorithms.traversal.depth_first_search.dfs_preorder_nodes")
(G\[, source, depth\_limit, ...\]) | Generate nodes in a depth-first-search pre-ordering starting at source. | | [`dfs_postorder_nodes`](generated/networkx.algorithms.traversal.depth_first_search.dfs_postorder_nodes.html#networkx.algorithms.traversal.depth_first_search.dfs_postorder_nodes "networkx.algorithms.traversal.depth_first_search.dfs_postorder_nodes")
(G\[, source, ...\]) | Generate nodes in a depth-first-search post-ordering starting at source. | | [`dfs_labeled_edges`](generated/networkx.algorithms.traversal.depth_first_search.dfs_labeled_edges.html#networkx.algorithms.traversal.depth_first_search.dfs_labeled_edges "networkx.algorithms.traversal.depth_first_search.dfs_labeled_edges")
(G\[, source, depth\_limit, ...\]) | Iterate over edges in a depth-first-search (DFS) labeled by type. | Breadth First Search[#](#module-networkx.algorithms.traversal.breadth_first_search "Link to this heading") ----------------------------------------------------------------------------------------------------------- Basic algorithms for breadth-first searching the nodes of a graph. | | | | --- | --- | | [`bfs_edges`](generated/networkx.algorithms.traversal.breadth_first_search.bfs_edges.html#networkx.algorithms.traversal.breadth_first_search.bfs_edges "networkx.algorithms.traversal.breadth_first_search.bfs_edges")
(G, source\[, reverse, depth\_limit, ...\]) | Iterate over edges in a breadth-first-search starting at source. | | [`bfs_layers`](generated/networkx.algorithms.traversal.breadth_first_search.bfs_layers.html#networkx.algorithms.traversal.breadth_first_search.bfs_layers "networkx.algorithms.traversal.breadth_first_search.bfs_layers")
(G, sources) | Returns an iterator of all the layers in breadth-first search traversal. | | [`bfs_tree`](generated/networkx.algorithms.traversal.breadth_first_search.bfs_tree.html#networkx.algorithms.traversal.breadth_first_search.bfs_tree "networkx.algorithms.traversal.breadth_first_search.bfs_tree")
(G, source\[, reverse, depth\_limit, ...\]) | Returns an oriented tree constructed from of a breadth-first-search starting at source. | | [`bfs_predecessors`](generated/networkx.algorithms.traversal.breadth_first_search.bfs_predecessors.html#networkx.algorithms.traversal.breadth_first_search.bfs_predecessors "networkx.algorithms.traversal.breadth_first_search.bfs_predecessors")
(G, source\[, depth\_limit, ...\]) | Returns an iterator of predecessors in breadth-first-search from source. | | [`bfs_successors`](generated/networkx.algorithms.traversal.breadth_first_search.bfs_successors.html#networkx.algorithms.traversal.breadth_first_search.bfs_successors "networkx.algorithms.traversal.breadth_first_search.bfs_successors")
(G, source\[, depth\_limit, ...\]) | Returns an iterator of successors in breadth-first-search from source. | | [`descendants_at_distance`](generated/networkx.algorithms.traversal.breadth_first_search.descendants_at_distance.html#networkx.algorithms.traversal.breadth_first_search.descendants_at_distance "networkx.algorithms.traversal.breadth_first_search.descendants_at_distance")
(G, source, distance) | Returns all nodes at a fixed `distance` from `source` in `G`. | | [`generic_bfs_edges`](generated/networkx.algorithms.traversal.breadth_first_search.generic_bfs_edges.html#networkx.algorithms.traversal.breadth_first_search.generic_bfs_edges "networkx.algorithms.traversal.breadth_first_search.generic_bfs_edges")
(G, source\[, neighbors, ...\]) | Iterate over edges in a breadth-first search. | Beam search[#](#module-networkx.algorithms.traversal.beamsearch "Link to this heading") ---------------------------------------------------------------------------------------- Basic algorithms for breadth-first searching the nodes of a graph. | | | | --- | --- | | [`bfs_beam_edges`](generated/networkx.algorithms.traversal.beamsearch.bfs_beam_edges.html#networkx.algorithms.traversal.beamsearch.bfs_beam_edges "networkx.algorithms.traversal.beamsearch.bfs_beam_edges")
(G, source, value\[, width\]) | Iterates over edges in a beam search. | Depth First Search on Edges[#](#module-networkx.algorithms.traversal.edgedfs "Link to this heading") ----------------------------------------------------------------------------------------------------- Algorithms for a depth-first traversal of edges in a graph. | | | | --- | --- | | [`edge_dfs`](generated/networkx.algorithms.traversal.edgedfs.edge_dfs.html#networkx.algorithms.traversal.edgedfs.edge_dfs "networkx.algorithms.traversal.edgedfs.edge_dfs")
(G\[, source, orientation\]) | A directed, depth-first-search of edges in `G`, beginning at `source`. | Breadth First Search on Edges[#](#module-networkx.algorithms.traversal.edgebfs "Link to this heading") ------------------------------------------------------------------------------------------------------- Algorithms for a breadth-first traversal of edges in a graph. | | | | --- | --- | | [`edge_bfs`](generated/networkx.algorithms.traversal.edgebfs.edge_bfs.html#networkx.algorithms.traversal.edgebfs.edge_bfs "networkx.algorithms.traversal.edgebfs.edge_bfs")
(G\[, source, orientation\]) | A directed, breadth-first-search of edges in `G`, beginning at `source`. | On this page --- # Triads — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Triads[#](#module-networkx.algorithms.triads "Link to this heading") ===================================================================== Functions for analyzing triads of a graph. | | | | --- | --- | | [`triadic_census`](generated/networkx.algorithms.triads.triadic_census.html#networkx.algorithms.triads.triadic_census "networkx.algorithms.triads.triadic_census")
(G\[, nodelist\]) | Determines the triadic census of a directed graph. | | [`random_triad`](generated/networkx.algorithms.triads.random_triad.html#networkx.algorithms.triads.random_triad "networkx.algorithms.triads.random_triad")
(G\[, seed\]) | Returns a random triad from a directed graph. | | [`triads_by_type`](generated/networkx.algorithms.triads.triads_by_type.html#networkx.algorithms.triads.triads_by_type "networkx.algorithms.triads.triads_by_type")
(G) | Returns a list of all triads for each triad type in a directed graph. | | [`triad_type`](generated/networkx.algorithms.triads.triad_type.html#networkx.algorithms.triads.triad_type "networkx.algorithms.triads.triad_type")
(G) | Returns the sociological triad type for a triad. | | [`is_triad`](generated/networkx.algorithms.triads.is_triad.html#networkx.algorithms.triads.is_triad "networkx.algorithms.triads.is_triad")
(G) | Returns True if the graph G is a triad, else False. | | [`all_triads`](generated/networkx.algorithms.triads.all_triads.html#networkx.algorithms.triads.all_triads "networkx.algorithms.triads.all_triads")
(G) | A generator of all possible triads in G. | | [`all_triplets`](generated/networkx.algorithms.triads.all_triplets.html#networkx.algorithms.triads.all_triplets "networkx.algorithms.triads.all_triplets")
(G) | Returns a generator of all possible sets of 3 nodes in a DiGraph. | --- # Tree — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Tree[#](#tree "Link to this heading") ====================================== Recognition[#](#module-networkx.algorithms.tree.recognition "Link to this heading") ------------------------------------------------------------------------------------ ### Recognition Tests[#](#recognition-tests "Link to this heading") A _forest_ is an acyclic, undirected graph, and a _tree_ is a connected forest. Depending on the subfield, there are various conventions for generalizing these definitions to directed graphs. In one convention, directed variants of forest and tree are defined in an identical manner, except that the direction of the edges is ignored. In effect, each directed edge is treated as a single undirected edge. Then, additional restrictions are imposed to define _branchings_ and _arborescences_. In another convention, directed variants of forest and tree correspond to the previous convention’s branchings and arborescences, respectively. Then two new terms, _polyforest_ and _polytree_, are defined to correspond to the other convention’s forest and tree. Summarizing: +-----------------------------+ | Convention A | Convention B | +=============================+ | forest | polyforest | | tree | polytree | | branching | forest | | arborescence | tree | +-----------------------------+ Each convention has its reasons. The first convention emphasizes definitional similarity in that directed forests and trees are only concerned with acyclicity and do not have an in-degree constraint, just as their undirected counterparts do not. The second convention emphasizes functional similarity in the sense that the directed analog of a spanning tree is a spanning arborescence. That is, take any spanning tree and choose one node as the root. Then every edge is assigned a direction such there is a directed path from the root to every other node. The result is a spanning arborescence. NetworkX follows convention “A”. Explicitly, these are: undirected forest An undirected graph with no undirected cycles. undirected tree A connected, undirected forest. directed forest A directed graph with no undirected cycles. Equivalently, the underlying graph structure (which ignores edge orientations) is an undirected forest. In convention B, this is known as a polyforest. directed tree A weakly connected, directed forest. Equivalently, the underlying graph structure (which ignores edge orientations) is an undirected tree. In convention B, this is known as a polytree. branching A directed forest with each node having, at most, one parent. So the maximum in-degree is equal to 1. In convention B, this is known as a forest. arborescence A directed tree with each node having, at most, one parent. So the maximum in-degree is equal to 1. In convention B, this is known as a tree. For trees and arborescences, the adjective “spanning” may be added to designate that the graph, when considered as a forest/branching, consists of a single tree/arborescence that includes all nodes in the graph. It is true, by definition, that every tree/arborescence is spanning with respect to the nodes that define the tree/arborescence and so, it might seem redundant to introduce the notion of “spanning”. However, the nodes may represent a subset of nodes from a larger graph, and it is in this context that the term “spanning” becomes a useful notion. | | | | --- | --- | | [`is_tree`](generated/networkx.algorithms.tree.recognition.is_tree.html#networkx.algorithms.tree.recognition.is_tree "networkx.algorithms.tree.recognition.is_tree")
(G) | Returns True if `G` is a tree. | | [`is_forest`](generated/networkx.algorithms.tree.recognition.is_forest.html#networkx.algorithms.tree.recognition.is_forest "networkx.algorithms.tree.recognition.is_forest")
(G) | Returns True if `G` is a forest. | | [`is_arborescence`](generated/networkx.algorithms.tree.recognition.is_arborescence.html#networkx.algorithms.tree.recognition.is_arborescence "networkx.algorithms.tree.recognition.is_arborescence")
(G) | Returns True if `G` is an arborescence. | | [`is_branching`](generated/networkx.algorithms.tree.recognition.is_branching.html#networkx.algorithms.tree.recognition.is_branching "networkx.algorithms.tree.recognition.is_branching")
(G) | Returns True if `G` is a branching. | Branchings and Spanning Arborescences[#](#module-networkx.algorithms.tree.branchings "Link to this heading") ------------------------------------------------------------------------------------------------------------- Algorithms for finding optimum branchings and spanning arborescences. This implementation is based on: > J. Edmonds, Optimum branchings, J. Res. Natl. Bur. Standards 71B (1967), 233–240. URL: [http://archive.org/details/jresv71Bn4p233](http://archive.org/details/jresv71Bn4p233) | | | | --- | --- | | [`branching_weight`](generated/networkx.algorithms.tree.branchings.branching_weight.html#networkx.algorithms.tree.branchings.branching_weight "networkx.algorithms.tree.branchings.branching_weight")
(G\[, attr, default\]) | Returns the total weight of a branching. | | [`greedy_branching`](generated/networkx.algorithms.tree.branchings.greedy_branching.html#networkx.algorithms.tree.branchings.greedy_branching "networkx.algorithms.tree.branchings.greedy_branching")
(G\[, attr, default, kind, seed\]) | Returns a branching obtained through a greedy algorithm. | | [`maximum_branching`](generated/networkx.algorithms.tree.branchings.maximum_branching.html#networkx.algorithms.tree.branchings.maximum_branching "networkx.algorithms.tree.branchings.maximum_branching")
(G\[, attr, default, ...\]) | Returns a maximum branching from G. | | [`minimum_branching`](generated/networkx.algorithms.tree.branchings.minimum_branching.html#networkx.algorithms.tree.branchings.minimum_branching "networkx.algorithms.tree.branchings.minimum_branching")
(G\[, attr, default, ...\]) | Returns a minimum branching from G. | | [`maximum_spanning_arborescence`](generated/networkx.algorithms.tree.branchings.maximum_spanning_arborescence.html#networkx.algorithms.tree.branchings.maximum_spanning_arborescence "networkx.algorithms.tree.branchings.maximum_spanning_arborescence")
(G\[, attr, ...\]) | Returns a maximum spanning arborescence from G. | | [`minimum_spanning_arborescence`](generated/networkx.algorithms.tree.branchings.minimum_spanning_arborescence.html#networkx.algorithms.tree.branchings.minimum_spanning_arborescence "networkx.algorithms.tree.branchings.minimum_spanning_arborescence")
(G\[, attr, ...\]) | Returns a minimum spanning arborescence from G. | | [`ArborescenceIterator`](generated/networkx.algorithms.tree.branchings.ArborescenceIterator.html#networkx.algorithms.tree.branchings.ArborescenceIterator "networkx.algorithms.tree.branchings.ArborescenceIterator")
(G\[, weight, minimum, ...\]) | Iterate over all spanning arborescences of a graph in either increasing or decreasing cost. | Encoding and decoding[#](#module-networkx.algorithms.tree.coding "Link to this heading") ----------------------------------------------------------------------------------------- Functions for encoding and decoding trees. Since a tree is a highly restricted form of graph, it can be represented concisely in several ways. This module includes functions for encoding and decoding trees in the form of nested tuples and Prüfer sequences. The former requires a rooted tree, whereas the latter can be applied to unrooted trees. Furthermore, there is a bijection from Prüfer sequences to labeled trees. | | | | --- | --- | | [`from_nested_tuple`](generated/networkx.algorithms.tree.coding.from_nested_tuple.html#networkx.algorithms.tree.coding.from_nested_tuple "networkx.algorithms.tree.coding.from_nested_tuple")
(sequence\[, ...\]) | Returns the rooted tree corresponding to the given nested tuple. | | [`to_nested_tuple`](generated/networkx.algorithms.tree.coding.to_nested_tuple.html#networkx.algorithms.tree.coding.to_nested_tuple "networkx.algorithms.tree.coding.to_nested_tuple")
(T, root\[, canonical\_form\]) | Returns a nested tuple representation of the given tree. | | [`from_prufer_sequence`](generated/networkx.algorithms.tree.coding.from_prufer_sequence.html#networkx.algorithms.tree.coding.from_prufer_sequence "networkx.algorithms.tree.coding.from_prufer_sequence")
(sequence) | Returns the tree corresponding to the given Prüfer sequence. | | [`to_prufer_sequence`](generated/networkx.algorithms.tree.coding.to_prufer_sequence.html#networkx.algorithms.tree.coding.to_prufer_sequence "networkx.algorithms.tree.coding.to_prufer_sequence")
(T) | Returns the Prüfer sequence of the given tree. | Operations[#](#module-networkx.algorithms.tree.operations "Link to this heading") ---------------------------------------------------------------------------------- Operations on trees. | | | | --- | --- | | [`join_trees`](generated/networkx.algorithms.tree.operations.join_trees.html#networkx.algorithms.tree.operations.join_trees "networkx.algorithms.tree.operations.join_trees")
(rooted\_trees, \*\[, ...\]) | Returns a new rooted tree made by joining `rooted_trees` | Spanning Trees[#](#module-networkx.algorithms.tree.mst "Link to this heading") ------------------------------------------------------------------------------- Algorithms for calculating min/max spanning trees/forests. | | | | --- | --- | | [`minimum_spanning_tree`](generated/networkx.algorithms.tree.mst.minimum_spanning_tree.html#networkx.algorithms.tree.mst.minimum_spanning_tree "networkx.algorithms.tree.mst.minimum_spanning_tree")
(G\[, weight, ...\]) | Returns a minimum spanning tree or forest on an undirected graph `G`. | | [`maximum_spanning_tree`](generated/networkx.algorithms.tree.mst.maximum_spanning_tree.html#networkx.algorithms.tree.mst.maximum_spanning_tree "networkx.algorithms.tree.mst.maximum_spanning_tree")
(G\[, weight, ...\]) | Returns a maximum spanning tree or forest on an undirected graph `G`. | | [`random_spanning_tree`](generated/networkx.algorithms.tree.mst.random_spanning_tree.html#networkx.algorithms.tree.mst.random_spanning_tree "networkx.algorithms.tree.mst.random_spanning_tree")
(G\[, weight, ...\]) | Sample a random spanning tree using the edges weights of `G`. | | [`minimum_spanning_edges`](generated/networkx.algorithms.tree.mst.minimum_spanning_edges.html#networkx.algorithms.tree.mst.minimum_spanning_edges "networkx.algorithms.tree.mst.minimum_spanning_edges")
(G\[, algorithm, ...\]) | Generate edges in a minimum spanning forest of an undirected weighted graph. | | [`maximum_spanning_edges`](generated/networkx.algorithms.tree.mst.maximum_spanning_edges.html#networkx.algorithms.tree.mst.maximum_spanning_edges "networkx.algorithms.tree.mst.maximum_spanning_edges")
(G\[, algorithm, ...\]) | Generate edges in a maximum spanning forest of an undirected weighted graph. | | [`SpanningTreeIterator`](generated/networkx.algorithms.tree.mst.SpanningTreeIterator.html#networkx.algorithms.tree.mst.SpanningTreeIterator "networkx.algorithms.tree.mst.SpanningTreeIterator")
(G\[, weight, minimum, ...\]) | Iterate over all spanning trees of a graph in either increasing or decreasing cost. | | [`number_of_spanning_trees`](generated/networkx.algorithms.tree.mst.number_of_spanning_trees.html#networkx.algorithms.tree.mst.number_of_spanning_trees "networkx.algorithms.tree.mst.number_of_spanning_trees")
(G, \*\[, root, weight\]) | Returns the number of spanning trees in `G`. | Decomposition[#](#module-networkx.algorithms.tree.decomposition "Link to this heading") ---------------------------------------------------------------------------------------- Function for computing a junction tree of a graph. | | | | --- | --- | | [`junction_tree`](generated/networkx.algorithms.tree.decomposition.junction_tree.html#networkx.algorithms.tree.decomposition.junction_tree "networkx.algorithms.tree.decomposition.junction_tree")
(G) | Returns a junction tree of a given graph. | Exceptions[#](#exceptions "Link to this heading") -------------------------------------------------- Functions for encoding and decoding trees. Since a tree is a highly restricted form of graph, it can be represented concisely in several ways. This module includes functions for encoding and decoding trees in the form of nested tuples and Prüfer sequences. The former requires a rooted tree, whereas the latter can be applied to unrooted trees. Furthermore, there is a bijection from Prüfer sequences to labeled trees. | | | | --- | --- | | [`NotATree`](generated/networkx.algorithms.tree.coding.NotATree.html#networkx.algorithms.tree.coding.NotATree "networkx.algorithms.tree.coding.NotATree") | Raised when a function expects a tree (that is, a connected undirected graph with no cycles) but gets a non-tree graph as input instead. | On this page --- # Vitality — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Vitality[#](#module-networkx.algorithms.vitality "Link to this heading") ========================================================================= Vitality measures. | | | | --- | --- | | [`closeness_vitality`](generated/networkx.algorithms.vitality.closeness_vitality.html#networkx.algorithms.vitality.closeness_vitality "networkx.algorithms.vitality.closeness_vitality")
(G\[, node, weight, ...\]) | Returns the closeness vitality for nodes in the graph. | --- # Voronoi cells — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Voronoi cells[#](#module-networkx.algorithms.voronoi "Link to this heading") ============================================================================= Functions for computing the Voronoi cells of a graph. | | | | --- | --- | | [`voronoi_cells`](generated/networkx.algorithms.voronoi.voronoi_cells.html#networkx.algorithms.voronoi.voronoi_cells "networkx.algorithms.voronoi.voronoi_cells")
(G, center\_nodes\[, weight\]) | Returns the Voronoi cells centered at `center_nodes` with respect to the shortest-path distance metric. | --- # Walks — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Walks[#](#module-networkx.algorithms.walks "Link to this heading") =================================================================== Function for computing walks in a graph. | | | | --- | --- | | [`number_of_walks`](generated/networkx.algorithms.walks.number_of_walks.html#networkx.algorithms.walks.number_of_walks "networkx.algorithms.walks.number_of_walks")
(G, walk\_length) | Returns the number of walks connecting each pair of nodes in `G` | --- # Adjacency List — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Adjacency List[#](#module-networkx.readwrite.adjlist "Link to this heading") ============================================================================= Read and write NetworkX graphs as adjacency lists. Adjacency list format is useful for graphs without data associated with nodes or edges and for nodes that can be meaningfully represented as strings. Format[#](#format "Link to this heading") ------------------------------------------ The adjacency list format consists of lines with node labels. The first label in a line is the source node. Further labels in the line are considered target nodes and are added to the graph along with an edge between the source node and target node. The graph with edges a-b, a-c, d-e can be represented as the following adjacency list (anything following the # in a line is a comment): a b c \# source target target d e | | | | --- | --- | | [`read_adjlist`](generated/networkx.readwrite.adjlist.read_adjlist.html#networkx.readwrite.adjlist.read_adjlist "networkx.readwrite.adjlist.read_adjlist")
(path\[, comments, delimiter, ...\]) | Read graph in adjacency list format from path. | | [`write_adjlist`](generated/networkx.readwrite.adjlist.write_adjlist.html#networkx.readwrite.adjlist.write_adjlist "networkx.readwrite.adjlist.write_adjlist")
(G, path\[, comments, ...\]) | Write graph G in single-line adjacency-list format to path. | | [`parse_adjlist`](generated/networkx.readwrite.adjlist.parse_adjlist.html#networkx.readwrite.adjlist.parse_adjlist "networkx.readwrite.adjlist.parse_adjlist")
(lines\[, comments, delimiter, ...\]) | Parse lines of a graph adjacency list representation. | | [`generate_adjlist`](generated/networkx.readwrite.adjlist.generate_adjlist.html#networkx.readwrite.adjlist.generate_adjlist "networkx.readwrite.adjlist.generate_adjlist")
(G\[, delimiter\]) | Generate a single line of the graph G in adjacency list format. | On this page --- # Wiener Index — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Wiener Index[#](#module-networkx.algorithms.wiener "Link to this heading") =========================================================================== Functions related to the Wiener Index of a graph. The Wiener Index is a topological measure of a graph related to the distance between nodes and their degree. The Schultz Index and Gutman Index are similar measures. They are used categorize molecules via the network of atoms connected by chemical bonds. The indices are correlated with functional aspects of the molecules. References[#](#references "Link to this heading") -------------------------------------------------- \[1\] [Wikipedia: Wiener Index](https://en.wikipedia.org/wiki/Wiener_index) \[2\] M.V. Diudeaa and I. Gutman, Wiener-Type Topological Indices, Croatica Chemica Acta, 71 (1998), 21-51. [https://hrcak.srce.hr/132323](https://hrcak.srce.hr/132323) | | | | --- | --- | | [`wiener_index`](generated/networkx.algorithms.wiener.wiener_index.html#networkx.algorithms.wiener.wiener_index "networkx.algorithms.wiener.wiener_index")
(G\[, weight\]) | Returns the Wiener index of the given graph. | | [`schultz_index`](generated/networkx.algorithms.wiener.schultz_index.html#networkx.algorithms.wiener.schultz_index "networkx.algorithms.wiener.schultz_index")
(G\[, weight\]) | Returns the Schultz Index (of the first kind) of `G` | | [`gutman_index`](generated/networkx.algorithms.wiener.gutman_index.html#networkx.algorithms.wiener.gutman_index "networkx.algorithms.wiener.gutman_index")
(G\[, weight\]) | Returns the Gutman Index for the graph `G`. | On this page --- # DOT — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") DOT[#](#dot "Link to this heading") ==================================== The [DOT graph description language](https://graphviz.org/doc/info/lang.html) defines a file format that is most often used in the context of graph visualization with [Graphviz](https://graphviz.org) . NetworkX provides an interface to Graphviz via [pygraphviz](https://pygraphviz.github.io/documentation/stable/index.html "(in PyGraphviz v1.14)") , implemented in [`nx_agraph`](../drawing.html#module-networkx.drawing.nx_agraph "networkx.drawing.nx_agraph") . If `pygraphviz` is installed, [`nx_agraph`](../drawing.html#module-networkx.drawing.nx_agraph "networkx.drawing.nx_agraph") can be used to read and write files in DOT format. pygraphviz[#](#pygraphviz "Link to this heading") -------------------------------------------------- | | | | --- | --- | | [`read_dot`](../generated/networkx.drawing.nx_agraph.read_dot.html#networkx.drawing.nx_agraph.read_dot "networkx.drawing.nx_agraph.read_dot")
(path) | Returns a NetworkX graph from a dot file on path. | | [`write_dot`](../generated/networkx.drawing.nx_agraph.write_dot.html#networkx.drawing.nx_agraph.write_dot "networkx.drawing.nx_agraph.write_dot")
(G, path) | Write NetworkX graph G to Graphviz dot format on path. | On this page --- # Multiline Adjacency List — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Multiline Adjacency List[#](#module-networkx.readwrite.multiline_adjlist "Link to this heading") ================================================================================================= Read and write NetworkX graphs as multi-line adjacency lists. The multi-line adjacency list format is useful for graphs with nodes that can be meaningfully represented as strings. With this format simple edge data can be stored but node or graph data is not. Format[#](#format "Link to this heading") ------------------------------------------ The first label in a line is the source node label followed by the node degree d. The next d lines are target node labels and optional edge data. That pattern repeats for all nodes in the graph. The graph with edges a-b, a-c, d-e can be represented as the following adjacency list (anything following the # in a line is a comment): \# example.multiline-adjlist a 2 b c d 1 e | | | | --- | --- | | [`read_multiline_adjlist`](generated/networkx.readwrite.multiline_adjlist.read_multiline_adjlist.html#networkx.readwrite.multiline_adjlist.read_multiline_adjlist "networkx.readwrite.multiline_adjlist.read_multiline_adjlist")
(path\[, comments, ...\]) | Read graph in multi-line adjacency list format from path. | | [`write_multiline_adjlist`](generated/networkx.readwrite.multiline_adjlist.write_multiline_adjlist.html#networkx.readwrite.multiline_adjlist.write_multiline_adjlist "networkx.readwrite.multiline_adjlist.write_multiline_adjlist")
(G, path\[, ...\]) | Write the graph G in multiline adjacency list format to path | | [`parse_multiline_adjlist`](generated/networkx.readwrite.multiline_adjlist.parse_multiline_adjlist.html#networkx.readwrite.multiline_adjlist.parse_multiline_adjlist "networkx.readwrite.multiline_adjlist.parse_multiline_adjlist")
(lines\[, comments, ...\]) | Parse lines of a multiline adjacency list representation of a graph. | | [`generate_multiline_adjlist`](generated/networkx.readwrite.multiline_adjlist.generate_multiline_adjlist.html#networkx.readwrite.multiline_adjlist.generate_multiline_adjlist "networkx.readwrite.multiline_adjlist.generate_multiline_adjlist")
(G\[, delimiter\]) | Generate a single line of the graph G in multiline adjacency list format. | On this page --- # Edge List — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Edge List[#](#module-networkx.readwrite.edgelist "Link to this heading") ========================================================================= Read and write NetworkX graphs as edge lists. The multi-line adjacency list format is useful for graphs with nodes that can be meaningfully represented as strings. With the edgelist format simple edge data can be stored but node or graph data is not. There is no way of representing isolated nodes unless the node has a self-loop edge. Format[#](#format "Link to this heading") ------------------------------------------ You can read or write three formats of edge lists with these functions. Node pairs with no data: 1 2 Python dictionary as data: 1 2 {'weight':7, 'color':'green'} Arbitrary data: 1 2 7 green | | | | --- | --- | | [`read_edgelist`](generated/networkx.readwrite.edgelist.read_edgelist.html#networkx.readwrite.edgelist.read_edgelist "networkx.readwrite.edgelist.read_edgelist")
(path\[, comments, delimiter, ...\]) | Read a graph from a list of edges. | | [`write_edgelist`](generated/networkx.readwrite.edgelist.write_edgelist.html#networkx.readwrite.edgelist.write_edgelist "networkx.readwrite.edgelist.write_edgelist")
(G, path\[, comments, ...\]) | Write graph as a list of edges. | | [`read_weighted_edgelist`](generated/networkx.readwrite.edgelist.read_weighted_edgelist.html#networkx.readwrite.edgelist.read_weighted_edgelist "networkx.readwrite.edgelist.read_weighted_edgelist")
(path\[, comments, ...\]) | Read a graph as list of edges with numeric weights. | | [`write_weighted_edgelist`](generated/networkx.readwrite.edgelist.write_weighted_edgelist.html#networkx.readwrite.edgelist.write_weighted_edgelist "networkx.readwrite.edgelist.write_weighted_edgelist")
(G, path\[, comments, ...\]) | Write graph G as a list of edges with numeric weights. | | [`generate_edgelist`](generated/networkx.readwrite.edgelist.generate_edgelist.html#networkx.readwrite.edgelist.generate_edgelist "networkx.readwrite.edgelist.generate_edgelist")
(G\[, delimiter, data\]) | Generate a single line of the graph G in edge list format. | | [`parse_edgelist`](generated/networkx.readwrite.edgelist.parse_edgelist.html#networkx.readwrite.edgelist.parse_edgelist "networkx.readwrite.edgelist.parse_edgelist")
(lines\[, comments, delimiter, ...\]) | Parse lines of an edge list representation of a graph. | On this page --- # GEXF — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") GEXF[#](#module-networkx.readwrite.gexf "Link to this heading") ================================================================ Read and write graphs in GEXF format. Warning This parser uses the standard xml library present in Python, which is insecure - see [`xml`](https://docs.python.org/3/library/xml.html#module-xml "(in Python v3.13)") for additional information. Only parse GEFX files you trust. GEXF (Graph Exchange XML Format) is a language for describing complex network structures, their associated data and dynamics. This implementation does not support mixed graphs (directed and undirected edges together). Format[#](#format "Link to this heading") ------------------------------------------ GEXF is an XML format. See [http://gexf.net/schema.html](http://gexf.net/schema.html) for the specification and [http://gexf.net/basic.html](http://gexf.net/basic.html) for examples. | | | | --- | --- | | [`read_gexf`](generated/networkx.readwrite.gexf.read_gexf.html#networkx.readwrite.gexf.read_gexf "networkx.readwrite.gexf.read_gexf")
(path\[, node\_type, relabel, version\]) | Read graph in GEXF format from path. | | [`write_gexf`](generated/networkx.readwrite.gexf.write_gexf.html#networkx.readwrite.gexf.write_gexf "networkx.readwrite.gexf.write_gexf")
(G, path\[, encoding, prettyprint, ...\]) | Write G in GEXF format to path. | | [`generate_gexf`](generated/networkx.readwrite.gexf.generate_gexf.html#networkx.readwrite.gexf.generate_gexf "networkx.readwrite.gexf.generate_gexf")
(G\[, encoding, prettyprint, ...\]) | Generate lines of GEXF format representation of G. | | [`relabel_gexf_graph`](generated/networkx.readwrite.gexf.relabel_gexf_graph.html#networkx.readwrite.gexf.relabel_gexf_graph "networkx.readwrite.gexf.relabel_gexf_graph")
(G) | Relabel graph using "label" node keyword for node label. | On this page --- # GML — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") GML[#](#module-networkx.readwrite.gml "Link to this heading") ============================================================== Read graphs in GML format. “GML, the Graph Modelling Language, is our proposal for a portable file format for graphs. GML’s key features are portability, simple syntax, extensibility and flexibility. A GML file consists of a hierarchical key-value lists. Graphs can be annotated with arbitrary data structures. The idea for a common file format was born at the GD’95; this proposal is the outcome of many discussions. GML is the standard file format in the Graphlet graph editor system. It has been overtaken and adapted by several other systems for drawing graphs.” GML files are stored using a 7-bit ASCII encoding with any extended ASCII characters (iso8859-1) appearing as HTML character entities. You will need to give some thought into how the exported data should interact with different languages and even different Python versions. Re-importing from gml is also a concern. Without specifying a `stringizer`/`destringizer`, the code is capable of writing [`int`](https://docs.python.org/3/library/functions.html#int "(in Python v3.13)") /[`float`](https://docs.python.org/3/library/functions.html#float "(in Python v3.13)") /[`str`](https://docs.python.org/3/library/stdtypes.html#str "(in Python v3.13)") /[`dict`](https://docs.python.org/3/library/stdtypes.html#dict "(in Python v3.13)") /[`list`](https://docs.python.org/3/library/stdtypes.html#list "(in Python v3.13)") data as required by the GML specification. For writing other data types, and for reading data other than [`str`](https://docs.python.org/3/library/stdtypes.html#str "(in Python v3.13)") you need to explicitly supply a `stringizer`/`destringizer`. For additional documentation on the GML file format, please see the [GML website](https://web.archive.org/web/20190207140002/http://www.fim.uni-passau.de/index.php?id=17297&L=1) . Several example graphs in GML format may be found on Mark Newman’s [Network data page](http://www-personal.umich.edu/~mejn/netdata/) . | | | | --- | --- | | [`read_gml`](generated/networkx.readwrite.gml.read_gml.html#networkx.readwrite.gml.read_gml "networkx.readwrite.gml.read_gml")
(path\[, label, destringizer\]) | Read graph in GML format from `path`. | | [`write_gml`](generated/networkx.readwrite.gml.write_gml.html#networkx.readwrite.gml.write_gml "networkx.readwrite.gml.write_gml")
(G, path\[, stringizer\]) | Write a graph `G` in GML format to the file or file handle `path`. | | [`parse_gml`](generated/networkx.readwrite.gml.parse_gml.html#networkx.readwrite.gml.parse_gml "networkx.readwrite.gml.parse_gml")
(lines\[, label, destringizer\]) | Parse GML graph from a string or iterable. | | [`generate_gml`](generated/networkx.readwrite.gml.generate_gml.html#networkx.readwrite.gml.generate_gml "networkx.readwrite.gml.generate_gml")
(G\[, stringizer\]) | Generate a single entry of the graph `G` in GML format. | | [`literal_destringizer`](generated/networkx.readwrite.gml.literal_destringizer.html#networkx.readwrite.gml.literal_destringizer "networkx.readwrite.gml.literal_destringizer")
(rep) | Convert a Python literal to the value it represents. | | [`literal_stringizer`](generated/networkx.readwrite.gml.literal_stringizer.html#networkx.readwrite.gml.literal_stringizer "networkx.readwrite.gml.literal_stringizer")
(value) | Convert a `value` to a Python literal in GML representation. | --- # GraphML — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") GraphML[#](#module-networkx.readwrite.graphml "Link to this heading") ====================================================================== Read and write graphs in GraphML format. Warning This parser uses the standard xml library present in Python, which is insecure - see [`xml`](https://docs.python.org/3/library/xml.html#module-xml "(in Python v3.13)") for additional information. Only parse GraphML files you trust. This implementation does not support mixed graphs (directed and unidirected edges together), hyperedges, nested graphs, or ports. “GraphML is a comprehensive and easy-to-use file format for graphs. It consists of a language core to describe the structural properties of a graph and a flexible extension mechanism to add application-specific data. Its main features include support of > * directed, undirected, and mixed graphs, > > * hypergraphs, > > * hierarchical graphs, > > * graphical representations, > > * references to external data, > > * application-specific attribute data, and > > * light-weight parsers. > Unlike many other file formats for graphs, GraphML does not use a custom syntax. Instead, it is based on XML and hence ideally suited as a common denominator for all kinds of services generating, archiving, or processing graphs.” [http://graphml.graphdrawing.org/](http://graphml.graphdrawing.org/) Format[#](#format "Link to this heading") ------------------------------------------ GraphML is an XML format. See [http://graphml.graphdrawing.org/specification.html](http://graphml.graphdrawing.org/specification.html) for the specification and [http://graphml.graphdrawing.org/primer/graphml-primer.html](http://graphml.graphdrawing.org/primer/graphml-primer.html) for examples. | | | | --- | --- | | [`read_graphml`](generated/networkx.readwrite.graphml.read_graphml.html#networkx.readwrite.graphml.read_graphml "networkx.readwrite.graphml.read_graphml")
(path\[, node\_type, ...\]) | Read graph in GraphML format from path. | | [`write_graphml`](generated/networkx.readwrite.graphml.write_graphml.html#networkx.readwrite.graphml.write_graphml "networkx.readwrite.graphml.write_graphml")
(G, path\[, encoding, ...\]) | Write G in GraphML XML format to path | | [`generate_graphml`](generated/networkx.readwrite.graphml.generate_graphml.html#networkx.readwrite.graphml.generate_graphml "networkx.readwrite.graphml.generate_graphml")
(G\[, encoding, prettyprint, ...\]) | Generate GraphML lines for G | | [`parse_graphml`](generated/networkx.readwrite.graphml.parse_graphml.html#networkx.readwrite.graphml.parse_graphml "networkx.readwrite.graphml.parse_graphml")
(graphml\_string\[, node\_type, ...\]) | Read graph in GraphML format from string. | On this page --- # JSON — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") JSON[#](#module-networkx.readwrite.json_graph "Link to this heading") ====================================================================== Generate and parse JSON serializable data for NetworkX graphs. These formats are suitable for use with the d3.js examples [https://d3js.org/](https://d3js.org/) The three formats that you can generate with NetworkX are: > * node-link like in the d3.js example [https://bl.ocks.org/mbostock/4062045](https://bl.ocks.org/mbostock/4062045) > > * tree like in the d3.js example [https://bl.ocks.org/mbostock/4063550](https://bl.ocks.org/mbostock/4063550) > > * adjacency like in the d3.js example [https://bost.ocks.org/mike/miserables/](https://bost.ocks.org/mike/miserables/) > | | | | --- | --- | | [`node_link_data`](generated/networkx.readwrite.json_graph.node_link_data.html#networkx.readwrite.json_graph.node_link_data "networkx.readwrite.json_graph.node_link_data")
(G, \*\[, source, target, name, ...\]) | Returns data in node-link format that is suitable for JSON serialization and use in JavaScript documents. | | [`node_link_graph`](generated/networkx.readwrite.json_graph.node_link_graph.html#networkx.readwrite.json_graph.node_link_graph "networkx.readwrite.json_graph.node_link_graph")
(data\[, directed, ...\]) | Returns graph from node-link data format. | | [`adjacency_data`](generated/networkx.readwrite.json_graph.adjacency_data.html#networkx.readwrite.json_graph.adjacency_data "networkx.readwrite.json_graph.adjacency_data")
(G\[, attrs\]) | Returns data in adjacency format that is suitable for JSON serialization and use in JavaScript documents. | | [`adjacency_graph`](generated/networkx.readwrite.json_graph.adjacency_graph.html#networkx.readwrite.json_graph.adjacency_graph "networkx.readwrite.json_graph.adjacency_graph")
(data\[, directed, ...\]) | Returns graph from adjacency data format. | | [`cytoscape_data`](generated/networkx.readwrite.json_graph.cytoscape_data.html#networkx.readwrite.json_graph.cytoscape_data "networkx.readwrite.json_graph.cytoscape_data")
(G\[, name, ident\]) | Returns data in Cytoscape JSON format (cyjs). | | [`cytoscape_graph`](generated/networkx.readwrite.json_graph.cytoscape_graph.html#networkx.readwrite.json_graph.cytoscape_graph "networkx.readwrite.json_graph.cytoscape_graph")
(data\[, name, ident\]) | Create a NetworkX graph from a dictionary in cytoscape JSON format. | | [`tree_data`](generated/networkx.readwrite.json_graph.tree_data.html#networkx.readwrite.json_graph.tree_data "networkx.readwrite.json_graph.tree_data")
(G, root\[, ident, children\]) | Returns data in tree format that is suitable for JSON serialization and use in JavaScript documents. | | [`tree_graph`](generated/networkx.readwrite.json_graph.tree_graph.html#networkx.readwrite.json_graph.tree_graph "networkx.readwrite.json_graph.tree_graph")
(data\[, ident, children\]) | Returns graph from tree data format. | --- # LEDA — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") LEDA[#](#module-networkx.readwrite.leda "Link to this heading") ================================================================ Read graphs in LEDA format. LEDA is a C++ class library for efficient data types and algorithms. Format[#](#format "Link to this heading") ------------------------------------------ See [http://www.algorithmic-solutions.info/leda\_guide/graphs/leda\_native\_graph\_fileformat.html](http://www.algorithmic-solutions.info/leda_guide/graphs/leda_native_graph_fileformat.html) | | | | --- | --- | | [`read_leda`](generated/networkx.readwrite.leda.read_leda.html#networkx.readwrite.leda.read_leda "networkx.readwrite.leda.read_leda")
(path\[, encoding\]) | Read graph in LEDA format from path. | | [`parse_leda`](generated/networkx.readwrite.leda.parse_leda.html#networkx.readwrite.leda.parse_leda "networkx.readwrite.leda.parse_leda")
(lines) | Read graph in LEDA format from string or iterable. | On this page --- # SparseGraph6 — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") SparseGraph6[#](#sparsegraph6 "Link to this heading") ====================================================== Functions for reading and writing graphs in the _graph6_ or _sparse6_ file formats. According to the author of these formats, > _graph6_ and _sparse6_ are formats for storing undirected graphs in a compact manner, using only printable ASCII characters. Files in these formats have text type and contain one line per graph. > > _graph6_ is suitable for small graphs, or large dense graphs. _sparse6_ is more space-efficient for large sparse graphs. > > —[graph6 and sparse6 homepage](http://users.cecs.anu.edu.au/~bdm/data/formats.html) Graph6[#](#module-networkx.readwrite.graph6 "Link to this heading") -------------------------------------------------------------------- Functions for reading and writing graphs in the _graph6_ format. The _graph6_ file format is suitable for small graphs or large dense graphs. For large sparse graphs, use the _sparse6_ format. For more information, see the [graph6](http://users.cecs.anu.edu.au/~bdm/data/formats.html) homepage. | | | | --- | --- | | [`from_graph6_bytes`](generated/networkx.readwrite.graph6.from_graph6_bytes.html#networkx.readwrite.graph6.from_graph6_bytes "networkx.readwrite.graph6.from_graph6_bytes")
(bytes\_in) | Read a simple undirected graph in graph6 format from bytes. | | [`read_graph6`](generated/networkx.readwrite.graph6.read_graph6.html#networkx.readwrite.graph6.read_graph6 "networkx.readwrite.graph6.read_graph6")
(path) | Read simple undirected graphs in graph6 format from path. | | [`to_graph6_bytes`](generated/networkx.readwrite.graph6.to_graph6_bytes.html#networkx.readwrite.graph6.to_graph6_bytes "networkx.readwrite.graph6.to_graph6_bytes")
(G\[, nodes, header\]) | Convert a simple undirected graph to bytes in graph6 format. | | [`write_graph6`](generated/networkx.readwrite.graph6.write_graph6.html#networkx.readwrite.graph6.write_graph6 "networkx.readwrite.graph6.write_graph6")
(G, path\[, nodes, header\]) | Write a simple undirected graph to a path in graph6 format. | Sparse6[#](#module-networkx.readwrite.sparse6 "Link to this heading") ---------------------------------------------------------------------- Functions for reading and writing graphs in the _sparse6_ format. The _sparse6_ file format is a space-efficient format for large sparse graphs. For small graphs or large dense graphs, use the _graph6_ file format. For more information, see the [sparse6](https://users.cecs.anu.edu.au/~bdm/data/formats.html) homepage. | | | | --- | --- | | [`from_sparse6_bytes`](generated/networkx.readwrite.sparse6.from_sparse6_bytes.html#networkx.readwrite.sparse6.from_sparse6_bytes "networkx.readwrite.sparse6.from_sparse6_bytes")
(string) | Read an undirected graph in sparse6 format from string. | | [`read_sparse6`](generated/networkx.readwrite.sparse6.read_sparse6.html#networkx.readwrite.sparse6.read_sparse6 "networkx.readwrite.sparse6.read_sparse6")
(path) | Read an undirected graph in sparse6 format from path. | | [`to_sparse6_bytes`](generated/networkx.readwrite.sparse6.to_sparse6_bytes.html#networkx.readwrite.sparse6.to_sparse6_bytes "networkx.readwrite.sparse6.to_sparse6_bytes")
(G\[, nodes, header\]) | Convert an undirected graph to bytes in sparse6 format. | | [`write_sparse6`](generated/networkx.readwrite.sparse6.write_sparse6.html#networkx.readwrite.sparse6.write_sparse6 "networkx.readwrite.sparse6.write_sparse6")
(G, path\[, nodes, header\]) | Write graph G to given path in sparse6 format. | On this page --- # Pajek — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Pajek[#](#module-networkx.readwrite.pajek "Link to this heading") ================================================================== Read graphs in Pajek format. This implementation handles directed and undirected graphs including those with self loops and parallel edges. Format[#](#format "Link to this heading") ------------------------------------------ See [http://vlado.fmf.uni-lj.si/pub/networks/pajek/doc/draweps.htm](http://vlado.fmf.uni-lj.si/pub/networks/pajek/doc/draweps.htm) for format information. | | | | --- | --- | | [`read_pajek`](generated/networkx.readwrite.pajek.read_pajek.html#networkx.readwrite.pajek.read_pajek "networkx.readwrite.pajek.read_pajek")
(path\[, encoding\]) | Read graph in Pajek format from path. | | [`write_pajek`](generated/networkx.readwrite.pajek.write_pajek.html#networkx.readwrite.pajek.write_pajek "networkx.readwrite.pajek.write_pajek")
(G, path\[, encoding\]) | Write graph in Pajek format to path. | | [`parse_pajek`](generated/networkx.readwrite.pajek.parse_pajek.html#networkx.readwrite.pajek.parse_pajek "networkx.readwrite.pajek.parse_pajek")
(lines) | Parse Pajek format graph from string or iterable. | | [`generate_pajek`](generated/networkx.readwrite.pajek.generate_pajek.html#networkx.readwrite.pajek.generate_pajek "networkx.readwrite.pajek.generate_pajek")
(G) | Generate lines in Pajek graph format. | On this page --- # Matrix Market — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Matrix Market[#](#matrix-market "Link to this heading") ======================================================== The [Matrix Market](https://math.nist.gov/MatrixMarket/formats.html) exchange format is a text-based file format described by NIST. Matrix Market supports both a **coordinate format** for sparse matrices and an **array format** for dense matrices. The [`scipy.io`](https://docs.scipy.org/doc/scipy/reference/io.html#module-scipy.io "(in SciPy v1.14.1)") module provides the [`scipy.io.mmread`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.io.mmread.html#scipy.io.mmread "(in SciPy v1.14.1)") and [`scipy.io.mmwrite`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.io.mmwrite.html#scipy.io.mmwrite "(in SciPy v1.14.1)") functions to read and write data in Matrix Market format, respectively. These functions work with either [`numpy.ndarray`](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray "(in NumPy v2.1)") or [`scipy.sparse.coo_matrix`](https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.coo_matrix.html#scipy.sparse.coo_matrix "(in SciPy v1.14.1)") objects depending on whether the data is in **array** or **coordinate** format. These functions can be combined with those of NetworkX’s [`convert_matrix`](../convert.html#module-networkx.convert_matrix "networkx.convert_matrix") module to read and write Graphs in Matrix Market format. Examples[#](#examples "Link to this heading") ---------------------------------------------- Reading and writing graphs using Matrix Market’s **array format** for dense matrices: \>>> import scipy as sp \>>> import io \# Use BytesIO as a stand-in for a Python file object \>>> fh \= io.BytesIO() \>>> G \= nx.complete\_graph(5) \>>> a \= nx.to\_numpy\_array(G) \>>> print(a) \[\[0. 1. 1. 1. 1.\]\ \[1. 0. 1. 1. 1.\]\ \[1. 1. 0. 1. 1.\]\ \[1. 1. 1. 0. 1.\]\ \[1. 1. 1. 1. 0.\]\] \>>> \# Write to file in Matrix Market array format \>>> sp.io.mmwrite(fh, a) \>>> print(fh.getvalue().decode('utf-8')) \# file contents %%MatrixMarket matrix array real symmetric % 5 5 0.0000000000000000e+00 1.0000000000000000e+00 1.0000000000000000e+00 1.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 1.0000000000000000e+00 1.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 1.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 1.0000000000000000e+00 0.0000000000000000e+00 \>>> \# Read from file \>>> fh.seek(0) \>>> H \= nx.from\_numpy\_array(sp.io.mmread(fh)) \>>> H.edges() \== G.edges() True Reading and writing graphs using Matrix Market’s **coordinate format** for sparse matrices: \>>> import scipy as sp \>>> import io \# Use BytesIO as a stand-in for a Python file object \>>> fh \= io.BytesIO() \>>> G \= nx.path\_graph(5) \>>> m \= nx.to\_scipy\_sparse\_array(G) \>>> print(m) (0, 1) 1 (1, 0) 1 (1, 2) 1 (2, 1) 1 (2, 3) 1 (3, 2) 1 (3, 4) 1 (4, 3) 1 \>>> sp.io.mmwrite(fh, m) \>>> print(fh.getvalue().decode('utf-8')) \# file contents %%MatrixMarket matrix coordinate integer symmetric % 5 5 4 2 1 1 3 2 1 4 3 1 5 4 1 \>>> \# Read from file \>>> fh.seek(0) \>>> H \= nx.from\_scipy\_sparse\_array(sp.io.mmread(fh)) \>>> H.edges() \== G.edges() True On this page --- # Network Text — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Network Text[#](#module-networkx.readwrite.text "Link to this heading") ======================================================================== Text-based visual representations of graphs | | | | --- | --- | | [`generate_network_text`](generated/networkx.readwrite.text.generate_network_text.html#networkx.readwrite.text.generate_network_text "networkx.readwrite.text.generate_network_text")
(graph\[, with\_labels, ...\]) | Generate lines in the "network text" format | | [`write_network_text`](generated/networkx.readwrite.text.write_network_text.html#networkx.readwrite.text.write_network_text "networkx.readwrite.text.write_network_text")
(graph\[, path, ...\]) | Creates a nice text representation of a graph | --- # _dispatchable — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") \_dispatchable[#](#dispatchable "Link to this heading") ======================================================== \_dispatchable(_func\=None_, _\*_, _name\=None_, _graphs\='G'_, _edge\_attrs\=None_, _node\_attrs\=None_, _preserve\_edge\_attrs\=False_, _preserve\_node\_attrs\=False_, _preserve\_graph\_attrs\=False_, _preserve\_all\_attrs\=False_, _mutates\_input\=False_, _returns\_graph\=False_)[\[source\]](../../_modules/networkx/utils/backends.html#_dispatchable) [#](#networkx.utils.backends._dispatchable "Link to this definition") A decorator function that is used to redirect the execution of `func` function to its backend implementation. This decorator function dispatches to a different backend implementation based on the input graph types, and it also manages all the `backend_kwargs`. Usage can be any of the following decorator forms: * `@_dispatchable` * `@_dispatchable()` * `@_dispatchable(name="override_name")` * `@_dispatchable(graphs="graph_var_name")` * `@_dispatchable(edge_attrs="weight")` * `@_dispatchable(graphs={"G": 0, "H": 1}, edge_attrs={"weight": "default"})` with 0 and 1 giving the position in the signature function for graph objects. When `edge_attrs` is a dict, keys are keyword names and values are defaults. Parameters: **func**callable, optional The function to be decorated. If `func` is not provided, returns a partial object that can be used to decorate a function later. If `func` is provided, returns a new callable object that dispatches to a backend algorithm based on input graph types. **name**str, optional The name of the algorithm to use for dispatching. If not provided, the name of `func` will be used. `name` is useful to avoid name conflicts, as all dispatched algorithms live in a single namespace. For example, `tournament.is_strongly_connected` had a name conflict with the standard `nx.is_strongly_connected`, so we used `@_dispatchable(name="tournament_is_strongly_connected")`. **graphs**str or dict or None, default “G” If a string, the parameter name of the graph, which must be the first argument of the wrapped function. If more than one graph is required for the algorithm (or if the graph is not the first argument), provide a dict keyed to argument names with argument position as values for each graph argument. For example, `@_dispatchable(graphs={"G": 0, "auxiliary?": 4})` indicates the 0th parameter `G` of the function is a required graph, and the 4th parameter `auxiliary?` is an optional graph. To indicate that an argument is a list of graphs, do `"[graphs]"`. Use `graphs=None`, if _no_ arguments are NetworkX graphs such as for graph generators, readers, and conversion functions. **edge\_attrs**str or dict, optional `edge_attrs` holds information about edge attribute arguments and default values for those edge attributes. If a string, `edge_attrs` holds the function argument name that indicates a single edge attribute to include in the converted graph. The default value for this attribute is 1. To indicate that an argument is a list of attributes (all with default value 1), use e.g. `"[attrs]"`. If a dict, `edge_attrs` holds a dict keyed by argument names, with values that are either the default value or, if a string, the argument name that indicates the default value. **node\_attrs**str or dict, optional Like `edge_attrs`, but for node attributes. **preserve\_edge\_attrs**bool or str or dict, optional For bool, whether to preserve all edge attributes. For str, the parameter name that may indicate (with `True` or a callable argument) whether all edge attributes should be preserved when converting. For dict of `{graph_name: {attr: default}}`, indicate pre-determined edge attributes (and defaults) to preserve for input graphs. **preserve\_node\_attrs**bool or str or dict, optional Like `preserve_edge_attrs`, but for node attributes. **preserve\_graph\_attrs**bool or set For bool, whether to preserve all graph attributes. For set, which input graph arguments to preserve graph attributes. **preserve\_all\_attrs**bool Whether to preserve all edge, node and graph attributes. This overrides all the other preserve\_\*\_attrs. **mutates\_input**bool or dict, default False For bool, whether the function mutates an input graph argument. For dict of `{arg_name: arg_pos}`, arguments that indicate whether an input graph will be mutated, and `arg_name` may begin with `"not "` to negate the logic (for example, this is used by `copy=` arguments). By default, dispatching doesn’t convert input graphs to a different backend for functions that mutate input graphs. **returns\_graph**bool, default False Whether the function can return or yield a graph object. By default, dispatching doesn’t convert input graphs to a different backend for functions that return graphs. On this page --- # Code of Conduct — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Code of Conduct[#](#code-of-conduct "Link to this heading") ============================================================ Introduction[#](#introduction "Link to this heading") ------------------------------------------------------ This code of conduct applies to all spaces managed by the NetworkX project, including all public and private mailing lists, issue trackers, wikis, and any other communication channel used by our community. This code of conduct should be honored by everyone who participates in the NetworkX community formally or informally, or claims any affiliation with the project, in any project-related activities and especially when representing the project, in any role. This code is not exhaustive or complete. It serves to distill our common understanding of a collaborative, shared environment and goals. Please try to follow this code in spirit as much as in letter, to create a friendly and productive environment that enriches the surrounding community. Specific Guidelines[#](#specific-guidelines "Link to this heading") -------------------------------------------------------------------- We strive to: 1. Be open. We invite anyone to participate in our community. We prefer to use public methods of communication for project-related messages, unless discussing something sensitive. This applies to messages for help or project-related support, too; not only is a public support request much more likely to result in an answer to a question, it also ensures that any inadvertent mistakes in answering are more easily detected and corrected. 2. Be empathetic, welcoming, friendly, and patient. We work together to resolve conflict, and assume good intentions. We may all experience some frustration from time to time, but we do not allow frustration to turn into a personal attack. A community where people feel uncomfortable or threatened is not a productive one. 3. Be collaborative. Our work will be used by other people, and in turn we will depend on the work of others. When we make something for the benefit of the project, we are willing to explain to others how it works, so that they can build on the work to make it even better. Any decision we make will affect users and colleagues, and we take those consequences seriously when making decisions. 4. Be inquisitive. Nobody knows everything! Asking questions early avoids many problems later, so we encourage questions, although we may direct them to the appropriate forum. We will try hard to be responsive and helpful. 5. Be careful in the words that we choose. We are careful and respectful in our communication and we take responsibility for our own speech. Be kind to others. Do not insult or put down other participants. We will not accept harassment or other exclusionary behaviour, such as: > * Violent threats or language directed against another person. > > * Sexist, racist, or otherwise discriminatory jokes and language. > > * Posting sexually explicit or violent material. > > * Posting (or threatening to post) other people’s personally identifying information (“doxing”). > > * Sharing private content, such as emails sent privately or non-publicly, or unlogged forums such as IRC channel history, without the sender’s consent. > > * Personal insults, especially those using racist or sexist terms. > > * Unwelcome sexual attention. > > * Excessive profanity. Please avoid swearwords; people differ greatly in their sensitivity to swearing. > > * Repeated harassment of others. In general, if someone asks you to stop, then stop. > > * Advocating for, or encouraging, any of the above behaviour. > Diversity Statement[#](#diversity-statement "Link to this heading") -------------------------------------------------------------------- The NetworkX project welcomes and encourages participation by everyone. We are committed to being a community that everyone enjoys being part of. Although we may not always be able to accommodate each individual’s preferences, we try our best to treat everyone kindly. No matter how you identify yourself or how others perceive you: we welcome you. Though no list can hope to be comprehensive, we explicitly honour diversity in: age, culture, ethnicity, genotype, gender identity or expression, language, national origin, neurotype, phenotype, political beliefs, profession, race, religion, sexual orientation, socioeconomic status, subculture and technical ability. Though we welcome people fluent in all languages, NetworkX development is conducted in English. Standards for behaviour in the NetworkX community are detailed in the Code of Conduct above. Participants in our community should uphold these standards in all their interactions and help others to do so as well (see next section). Reporting Guidelines[#](#reporting-guidelines "Link to this heading") ---------------------------------------------------------------------- We know that it is painfully common for internet communication to start at or devolve into obvious and flagrant abuse. We also recognize that sometimes people may have a bad day, or be unaware of some of the guidelines in this Code of Conduct. Please keep this in mind when deciding on how to respond to a breach of this Code. For clearly intentional breaches, report those to the NetworkX Steering Council (see below). For possibly unintentional breaches, you may reply to the person and point out this code of conduct (either in public or in private, whatever is most appropriate). If you would prefer not to do that, please feel free to report to the NetworkX Steering Council directly, or ask the Council for advice, in confidence. You can report issues to the [NetworkX Steering Council](https://github.com/orgs/networkx/teams/steering-council/members) , at [networkx-conduct@groups.io](mailto:networkx-conduct%40groups.io) . If your report involves any members of the Council, or if they feel they have a conflict of interest in handling it, then they will recuse themselves from considering your report. Alternatively, if for any reason you feel uncomfortable making a report to the Council, then you can also contact: * Senior [NumFOCUS staff](https://numfocus.org/code-of-conduct#persons-responsible) : [conduct@numfocus.org](mailto:conduct%40numfocus.org) . Incident reporting resolution & Code of Conduct enforcement[#](#incident-reporting-resolution-code-of-conduct-enforcement "Link to this heading") -------------------------------------------------------------------------------------------------------------------------------------------------- We will investigate and respond to all complaints. The NetworkX Steering Council will protect the identity of the reporter, and treat the content of complaints as confidential (unless the reporter agrees otherwise). In case of severe and obvious breaches, e.g., personal threat or violent, sexist or racist language, we will immediately disconnect the originator from NetworkX communication channels. In cases not involving clear severe and obvious breaches of this code of conduct, the process for acting on any received code of conduct violation report will be: 1. acknowledge report is received 2. reasonable discussion/feedback 3. mediation (if feedback didn’t help, and only if both reporter and reportee agree to this) 4. enforcement via transparent decision by the NetworkX Steering Council The Council will respond to any report as soon as possible, and at most within 72 hours. Endnotes[#](#endnotes "Link to this heading") ---------------------------------------------- This document is adapted from: * [SciPy Code of Conduct](http://scipy.github.io/devdocs/dev/conduct/code_of_conduct.html) On this page --- # About Us — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") About Us[#](#about-us "Link to this heading") ============================================== NetworkX was originally written by Aric Hagberg, Dan Schult, and Pieter Swart, and has been developed with the help of many others. Thanks to everyone who has improved NetworkX by contributing code, bug reports (and fixes), documentation, and input on design, features, and the future of NetworkX. Core Developers[#](#core-developers "Link to this heading") ------------------------------------------------------------ NetworkX development is guided by the following core team: [![Avatar picture of @boothby](https://avatars.githubusercontent.com/u/569654?v=4&s=40)\ \ Kelly Boothby](https://github.com/boothby) @boothby [![Avatar picture of @dschult](https://avatars.githubusercontent.com/u/915037?v=4&s=40)\ \ Dan Schult](https://github.com/dschult) @dschult [![Avatar picture of @eriknw](https://avatars.githubusercontent.com/u/2058401?v=4&s=40)\ \ Erik Welch](https://github.com/eriknw) @eriknw [![Avatar picture of @hagberg](https://avatars.githubusercontent.com/u/187875?v=4&s=40)\ \ Aric Hagberg](https://github.com/hagberg) @hagberg [![Avatar picture of @jarrodmillman](https://avatars.githubusercontent.com/u/123428?v=4&s=40)\ \ Jarrod Millman](https://github.com/jarrodmillman) @jarrodmillman [![Avatar picture of @mjschwenne](https://avatars.githubusercontent.com/u/19698215?v=4&s=40)\ \ Matt Schwennesen](https://github.com/mjschwenne) @mjschwenne [![Avatar picture of @MridulS](https://avatars.githubusercontent.com/u/5363860?v=4&s=40)\ \ Mridul Seth](https://github.com/MridulS) @MridulS [![Avatar picture of @rossbar](https://avatars.githubusercontent.com/u/1268991?v=4&s=40)\ \ Ross Barnowski](https://github.com/rossbar) @rossbar [![Avatar picture of @Schefflera-Arboricola](https://avatars.githubusercontent.com/u/91629733?v=4&s=40)\ \ Aditi Juneja](https://github.com/Schefflera-Arboricola) @Schefflera-Arboricola [![Avatar picture of @stefanv](https://avatars.githubusercontent.com/u/45071?v=4&s=40)\ \ Stefan van der Walt](https://github.com/stefanv) @stefanv Emeritus Developers[#](#emeritus-developers "Link to this heading") -------------------------------------------------------------------- We thank these previously-active core developers for their contributions to NetworkX. [![Avatar picture of @bjedwards](https://avatars.githubusercontent.com/u/726274?v=4&s=40)\ \ Benjamin Edwards](https://github.com/bjedwards) @bjedwards [![Avatar picture of @camillescott](https://avatars.githubusercontent.com/u/2896301?v=4&s=40)\ \ Camille Scott](https://github.com/camillescott) @camillescott [![Avatar picture of @chebee7i](https://avatars.githubusercontent.com/u/326005?v=4&s=40)\ \ @chebee7i](https://github.com/chebee7i) @chebee7i [![Avatar picture of @ericmjl](https://avatars.githubusercontent.com/u/2631566?v=4&s=40)\ \ Eric Ma](https://github.com/ericmjl) @ericmjl [![Avatar picture of @harshal-dupare](https://avatars.githubusercontent.com/u/52428908?v=4&s=40)\ \ Harshal Dupare](https://github.com/harshal-dupare) @harshal-dupare [![Avatar picture of @jfinkels](https://avatars.githubusercontent.com/u/121755?v=4&s=40)\ \ @jfinkels](https://github.com/jfinkels) @jfinkels [![Avatar picture of @jtorrents](https://avatars.githubusercontent.com/u/1184374?v=4&s=40)\ \ Jordi Torrents](https://github.com/jtorrents) @jtorrents [![Avatar picture of @loicseguin](https://avatars.githubusercontent.com/u/812562?v=4&s=40)\ \ Loïc Séguin-Charbonneau](https://github.com/loicseguin) @loicseguin [![Avatar picture of @paulitapb](https://avatars.githubusercontent.com/u/44149844?v=4&s=40)\ \ Paula Pérez Bianchi](https://github.com/paulitapb) @paulitapb [![Avatar picture of @vadyushkins](https://avatars.githubusercontent.com/u/43042296?v=4&s=40)\ \ Vadim](https://github.com/vadyushkins) @vadyushkins [![Avatar picture of @z3y50n](https://avatars.githubusercontent.com/u/33282622?v=4&s=40)\ \ Dimitrios Papageorgiou](https://github.com/z3y50n) @z3y50n Steering Council[#](#steering-council "Link to this heading") -------------------------------------------------------------- [![Avatar picture of @boothby](https://avatars.githubusercontent.com/u/569654?v=4&s=40)\ \ Kelly Boothby](https://github.com/boothby) @boothby [![Avatar picture of @dschult](https://avatars.githubusercontent.com/u/915037?v=4&s=40)\ \ Dan Schult](https://github.com/dschult) @dschult [![Avatar picture of @hagberg](https://avatars.githubusercontent.com/u/187875?v=4&s=40)\ \ Aric Hagberg](https://github.com/hagberg) @hagberg [![Avatar picture of @jarrodmillman](https://avatars.githubusercontent.com/u/123428?v=4&s=40)\ \ Jarrod Millman](https://github.com/jarrodmillman) @jarrodmillman [![Avatar picture of @MridulS](https://avatars.githubusercontent.com/u/5363860?v=4&s=40)\ \ Mridul Seth](https://github.com/MridulS) @MridulS [![Avatar picture of @rossbar](https://avatars.githubusercontent.com/u/1268991?v=4&s=40)\ \ Ross Barnowski](https://github.com/rossbar) @rossbar [![Avatar picture of @stefanv](https://avatars.githubusercontent.com/u/45071?v=4&s=40)\ \ Stefan van der Walt](https://github.com/stefanv) @stefanv Contributors[#](#contributors "Link to this heading") ------------------------------------------------------ If you are a NetworkX contributor, please feel free to open an [issue](https://github.com/networkx/networkx/issues/new) or submit a [pull request](https://github.com/networkx/networkx/compare/) to add your name to the bottom of the list. * Aric Hagberg, GitHub: [hagberg](https://github.com/hagberg) * Dan Schult, GitHub: [dschult](https://github.com/dschult) * Pieter Swart * Katy Bold * Hernan Rozenfeld * Brendt Wohlberg * Jim Bagrow * Holly Johnsen * Arnar Flatberg * Chris Myers * Joel Miller * Keith Briggs * Ignacio Rozada * Phillipp Pagel * Sverre Sundsdal * Ross M. Richardson * Eben Kenah * Sasha Gutfriend * Udi Weinsberg * Matteo Dell’Amico * Andrew Conway * Raf Guns * Salim Fadhley * Fabrice Desclaux * Arpad Horvath * Minh Van Nguyen * Willem Ligtenberg * Loïc Séguin-C. * Paul McGuire * Jesus Cerquides * Ben Edwards * Jon Olav Vik * Hugh Brown * Ben Reilly * Leo Lopes * Jordi Torrents, GitHub: [jtorrents](https://github.com/jtorrents) * Dheeraj M R, GitHub: [dheerajrav](https://github.com/dheerajrav) * Franck Kalala * Simon Knight * Conrad Lee * Sérgio Nery Simões * Robert King * Nick Mancuso * Brian Cloteaux * Alejandro Weinstein * Dustin Smith * Mathieu Larose * Romain Fontugne * Vincent Gauthier * chebee7i, GitHub: [chebee7i](https://github.com/chebee7i) * Jeffrey Finkelstein * Jean-Gabriel Young, GitHub: [jg-you](https://github.com/jgyou) * Andrey Paramonov, [http://aparamon.msk.ru](http://aparamon.msk.ru) * Mridul Seth, GitHub: [MridulS](https://github.com/MridulS) * Thodoris Sotiropoulos, GitHub: [theosotr](https://github.com/theosotr) * Konstantinos Karakatsanis, GitHub: [k-karakatsanis](https://github.com/k-karakatsanis) * Ryan Nelson, GitHub: [rnelsonchem](https://github.com/rnelsonchem) * Niels van Adrichem, GitHub: [NvanAdrichem](https://github.com/NvanAdrichem) * Michael E. Rose, GitHub: [Michael-E-Rose](https://github.com/Michael-E-Rose) * Jarrod Millman, GitHub: [jarrodmillman](https://github.com/jarrodmillman) * Andre Weltsch * Lewis Robbins * Mads Jensen, GitHub: [atombrella](https://github.com/atombrella) * Edward L. Platt, [elplatt](https://elplatt.com) * James Owen, GitHub: [leamingrad](https://github.com/leamingrad) * Robert Gmyr, GitHub: [gmyr](https://github.com/gmyr) * Mike Trenfield * Jon Crall, GitHub: [Erotemic](https://github.com/Erotemic) * Issa Moradnejad, GitHub: [Moradnejad](https://github.com/Moradnejad) , LinkedIn: [Issa Moradnejad](https://linkedin.com/in/moradnejad/) * Brian Kiefer, GitHub: [bkief](https://github.com/bkief) * Julien Klaus * Peter C. Kroon, GitHub: [pckroon](https://github.com/pckroon) * Weisheng Si, GitHub: [ws4u](https://github.com/ws4u) * Haakon H. Rød, GitLab: [haakonhr](https://gitlab.com/haakonhr) , [https://haakonhr.gitlab.io](https://haakonhr.gitlab.io) * Efraim Rodrigues, GitHub: [efraimrodrigues](https://github.com/efraimrodrigues) , LinkedIn: [efraim-rodrigues](https://linkedin.com/in/efraim-rodrigues/) * Erwan Le Merrer * Søren Fuglede Jørgensen, GitHub: [fuglede](https://github.com/fuglede) * Salim BELHADDAD, LinkedIn: [salymdotme](https://www.linkedin.com/in/salymdotme/) * Jangwon Yie, GitHub: [jangwon-yie](https://github.com/jangwon-yie) , LinkedIn: [jangwon-yie-a7960065](https://www.linkedin.com/in/jangwon-yie-a7960065/) * ysitu * Tomas Gavenciak * Luca Baldesi * Yuto Yamaguchi * James Clough * Minas Gjoka * Drew Conway * Alex Levenson * Haochen Wu * Erwan Le Merrer * Alex Roper * P C Kroon * Christopher Ellison * 4. Eppstein * Federico Rosato * Aitor Almeida * Ferran Parés * Christian Olsson * Fredrik Erlandsson * Nanda H Krishna * Nicholas Mancuso * Fred Morstatter * Ollie Glass * Rodrigo Dorantes-Gilardi * Pranay Kanwar * Balint Tillman * Diederik van Liere * Ferdinando Papale * Miguel Sozinho Ramalho * Brandon Liu * Nima Mohammadi * Jason Grout * Jan Aagaard Meier * Henrik Haugbølle * Piotr Brodka * Sasha Gutfraind * Alessandro Luongo * Huston Hedinger * Oleguer Sagarra * Kazimierz Wojciechowski, GitHub: [kazimierz-256](https://github.com/kazimierz-256) , LinkedIn: [wojciechowski-kazimierz](https://linkedin.com/in/wojciechowski-kazimierz/) * Gaetano Pietro Paolo Carpinato, GitHub: [Carghaez](https://github.com/Carghaez) , LinkedIn: [gaetanocarpinato](https://linkedin.com/in/gaetanocarpinato/) * Arun Nampally, GitHub: [arunwise](https://github.com/arunwise) , LinkedIn: [arun-nampally-b57845b7](https://www.linkedin.com/in/arun-nampally-b57845b7/) * Ryan Duve * Shashi Prakash Tripathi, GitHub: [itsshavar](https://github.com/itsshavar) , LinkedIn: [itsshashitripathi](https://www.linkedin.com/in/itsshashitripathi/) * Danny Niquette * James Trimble, GitHub: [jamestrimble](https://github.com/jamestrimble) * Matthias Bruhns, GitHub: [mbruhns](https://github.com/mbruhns) * Philip Boalch * Matt Schwennesen, GitHub: [mjschwenne](https://github.com/mjschwenne) * Andrew Knyazev, GitHub: [lobpcg](https://github.com/lobpcg) , LinkedIn: [andrew-knyazev](https://www.linkedin.com/in/andrew-knyazev) * Luca Cappelletti, GitHub: [LucaCappelletti94](https://github.com/LucaCappelletti94) * Sultan Orazbayev, GitHub: [SultanOrazbayev](https://github.com/SultanOrazbayev) , LinkedIn: [Sultan Orazbayev](https://www.linkedin.com/in/sultan-orazbayev/) * Paolo Boldi, Github: `https://github.com/boldip` * Davide D’Ascenzo, Github: `https://github.com/kidara` * Flavio Furia, Github: `https://github.com/flaviofuria` * Sebastiano Vigna, Github: `https://github.com/vigna` * Aaron Zolnai-Lucas, GitHub: [aaronzo](https://github.com/aaronzo) , LinkedIn: [aaronzolnailucas](https://www.linkedin.com/in/aaronzolnailucas/) * Erik Welch, GitHub: [eriknw](https://github.com/eriknw) , LinkedIn: [eriknwelch](https://www.linkedin.com/in/eriknwelch/) * Mohamed Rezk, Github: [mohamedrezk122](https://github.com/mohamedrezk122) * Orion Sehn, GitHub: [OrionSehn](https://github.com/OrionSehn) A supplementary (but still incomplete) list of contributors is given by the list of names that have commits in `networkx`’s [git](http://git-scm.com) repository. This can be obtained via: git log \--raw | grep "^Author: " | sort | uniq A historical, partial listing of contributors and their contributions to some of the earlier versions of NetworkX can be found [here](https://github.com/networkx/networkx/blob/886e790437bcf30e9f58368829d483efef7a2acc/doc/source/reference/credits_old.rst) . Support[#](#support "Link to this heading") -------------------------------------------- NetworkX acknowledges support from the following research groups: * [Center for Nonlinear Studies](http://cnls.lanl.gov) , Los Alamos National Laboratory, PI: Aric Hagberg * [Open Source Programs Office](https://developers.google.com/open-source/) , Google * [Complexity Sciences Center](http://csc.ucdavis.edu/) , Department of Physics, University of California-Davis, PI: James P. Crutchfield * [Center for Complexity and Collective Computation](http://c4.discovery.wisc.edu) , Wisconsin Institute for Discovery, University of Wisconsin-Madison, PIs: Jessica C. Flack and David C. Krakauer NetworkX acknowledges the following financial support: * Google Summer of Code via Python Software Foundation * U.S. Army Research Office grant W911NF-12-1-0288 * DARPA Physical Intelligence Subcontract No. 9060-000709 * NSF Grant No. PHY-0748828 * John Templeton Foundation through a grant to the Santa Fe Institute to study complexity * U.S. Army Research Laboratory and the U.S. Army Research Office under contract number W911NF-13-1-0340 On this page --- # Mission and Values — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Mission and Values[#](#mission-and-values "Link to this heading") ================================================================== Our mission[#](#our-mission "Link to this heading") ---------------------------------------------------- NetworkX aims to be the reference library for network science algorithms in Python. We accomplish this by: * **being easy to use and install**. We are careful in taking on new dependencies, and sometimes cull existing ones, or make them optional. All functions in our API have thorough docstrings clarifying expected inputs and outputs. * **providing a consistent API**. Conceptually identical arguments have the same name and position in a function signature. * **ensuring correctness**. Test coverage is close to 100% and code is reviewed by at least two core developers before being included in the library. * **caring for users’ data**. We have a functional API and don’t modify input data unless explicitly directed to do so. * **promoting education in network science**, with extensive pedagogical documentation. Our values[#](#our-values "Link to this heading") -------------------------------------------------- * We are inclusive ([Code of Conduct](code_of_conduct.html#code-of-conduct) ). We welcome and mentor newcomers who are making their first contribution. * We are open source and community-driven ([NXEP 1 — Governance and Decision Making](nxeps/nxep-0001.html#governance) ). * We focus on graph data structures and algorithms for network science applications. * We prefer pure Python implementations using native data structures (especially dicts) due to their consistent, intuitive interface and amazing performance capabilities. We include interfaces to other data structures, especially NumPy arrays and SciPy sparse matrices for algorithms that more naturally use arrays and matrices or where time or space requirements are significantly lower. Sometimes we provide two algorithms for the same result, one using each data structure, when pedagogy or space/time trade-offs justify such multiplicity. * We value simple, readable implementations over getting every last ounce of performance. Readable code that is easy to understand, for newcomers and maintainers alike, makes it easier to contribute new code as well as prevent bugs. This means that we will prefer a 20% slowdown if it reduces lines of code two-fold, for example. * We value education and documentation. All functions should have `NumPy-style docstrings`, preferably with examples, as well as gallery examples that showcase how that function is used in a scientific application. Acknowledgments[#](#acknowledgments "Link to this heading") ------------------------------------------------------------ This document is modified from the `scikit-image` mission and values document. On this page --- # Algorithms — NetworkX Notebooks [Skip to main content](#main-content) Back to top Ctrl+K [![NetworkX Notebooks - Home](../../_static/networkx_banner.svg) ![NetworkX Notebooks - Home](../../_static/networkx_banner.svg)](../../index.html) * [GitHub](https://github.com/networkx/nx-guides/ "GitHub") Search Ctrl+K * [Repository](https://github.com/networkx/nx-guides "Source repository") * [Suggest edit](https://github.com/networkx/nx-guides/edit/main/site/content/algorithms/index.md "Suggest edit") * [Open issue](https://github.com/networkx/nx-guides/issues/new?title=Issue%20on%20page%20%2Fcontent/algorithms/index.html&body=Your%20issue%20content%20here. "Open an issue") * [.md](../../_sources/content/algorithms/index.md "Download source file") * .pdf Algorithms ========== Algorithms[#](#algorithms "Link to this heading") ================================================== A closer look at some of the algorithms and network analysis techniques provided by NetworkX. * [Node Assortativity Coefficients and Correlation Measures](assortativity/correlation.html) * [Directed Acyclic Graphs & Topological Sort](dag/index.html) * [Dinitz’s Algorithm and Applications](flow/dinitz_alg.html) * [Lowest Common Ancestor](lca/LCA.html) * [Euler’s Algorithm](euler/euler.html) * [Isomorphism - How to find if two graphs are similar?](isomorphism/isomorphism.html) --- # Contributor Guide — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Contributor Guide[#](#contributor-guide "Link to this heading") ================================================================ Note This document assumes some familiarity with contributing to open source scientific Python projects using GitHub pull requests. If this does not describe you, you may first want to see the [New Contributor FAQ](new_contributor_faq.html#contributing-faq) . If you are using a LLM or any other AI model, you will still need to follow the process described here. Development Workflow[#](#development-workflow "Link to this heading") ---------------------------------------------------------------------- 1. If you are a first-time contributor: * Go to [networkx/networkx](https://github.com/networkx/networkx) and click the “fork” button to create your own copy of the project. * Clone the project to your local computer: git clone git@github.com:your\-username/networkx.git * Navigate to the folder networkx and add the upstream repository: git remote add upstream git@github.com:networkx/networkx.git * Now, you have remote repositories named: * `upstream`, which refers to the `networkx` repository * `origin`, which refers to your personal fork * Next, you need to set up your build environment. Here are instructions for two popular environment managers: * `venv` (pip based) \# Create a virtualenv named \`\`networkx-dev\`\` that lives in the directory of \# the same name python \-m venv networkx\-dev \# Activate it source networkx\-dev/bin/activate \# Install main development and runtime dependencies of networkx pip install \-r requirements/default.txt \-r requirements/test.txt \-r requirements/developer.txt # \# (Optional) Install pygraphviz and pydot packages \# These packages require that you have your system properly configured \# and what that involves differs on various systems. \# pip install -r requirements/extra.txt # \# Build and install networkx from source pip install \-e . \# Test your installation pytest \--pyargs networkx * `conda` (Anaconda or Miniconda) \# Create a conda environment named \`\`networkx-dev\`\` conda create \--name networkx\-dev \# Activate it conda activate networkx\-dev \# Install main development and runtime dependencies of networkx conda install \-c conda\-forge \--file requirements/default.txt \--file requirements/test.txt \--file requirements/developer.txt # \# (Optional) Install pygraphviz and pydot packages \# These packages require that you have your system properly configured \# and what that involves differs on various systems. \# conda install -c conda-forge --file requirements/extra.txt # \# Install networkx from source pip install \-e . \# Test your installation pytest \--pyargs networkx * Finally, we recommend you install pre-commit which checks that your code matches formatting guidelines: pre\-commit install 2. Develop your contribution: * Pull the latest changes from upstream: git checkout main git pull upstream main * Create a branch for the feature you want to work on. Since the branch name will appear in the merge message, use a sensible name such as ‘bugfix-for-issue-1480’: git checkout \-b bugfix\-for\-issue\-1480 main * Commit locally as you progress (`git add` and `git commit`) 3. Test your contribution: * Run the test suite locally (see [Testing](#testing) for details): PYTHONPATH\=. pytest networkx * Running the tests locally _before_ submitting a pull request helps catch problems early and reduces the load on the continuous integration system. 4. Ensure your contribution is properly formatted. * If you installed `pre-commit` as recommended in step 1, all necessary linting should run automatically at commit time. If there are any formatting issues, the commit will not be successful and linting suggestions will be applied to the patch automatically. Simply `git add` and `git commit` a second time to accept the proposed formatting changes. * If the above fails for whatever reason, you can also run the linter over the entire codebase with: pre\-commit run \--all\-files 5. Submit your contribution: * Push your changes back to your fork on GitHub: git push origin bugfix\-for\-issue\-1480 * Go to GitHub. The new branch will show up with a green Pull Request button—click it. * If you want, post on the [mailing list](http://groups.google.com/group/networkx-discuss) to explain your changes or to ask for review. 6. Review process: * Every Pull Request (PR) update triggers a set of [continuous integration](https://en.wikipedia.org/wiki/Continuous_integration) services that check that the code is up to standards and passes all our tests. These checks must pass before your PR can be merged. If one of the checks fails, you can find out why by clicking on the “failed” icon (red cross) and inspecting the build and test log. * Reviewers (the other developers and interested community members) will write inline and/or general comments on your PR to help you improve its implementation, documentation, and style. Every single developer working on the project has their code reviewed, and we’ve come to see it as friendly conversation from which we all learn and the overall code quality benefits. Therefore, please don’t let the review discourage you from contributing: its only aim is to improve the quality of project, not to criticize (we are, after all, very grateful for the time you’re donating!). * To update your PR, make your changes on your local repository and commit. As soon as those changes are pushed up (to the same branch as before) the PR will update automatically. Note If the PR closes an issue, make sure that GitHub knows to automatically close the issue when the PR is merged. For example, if the PR closes issue number 1480, you could use the phrase “Fixes #1480” in the PR description or commit message. 7. Document deprecations and API changes If your change introduces any API modifications including deprecations, please make sure the PR has the `type: API` label. To set up a function for deprecation: * Use a deprecation warning to warn users. For example: msg \= "curly\_hair is deprecated and will be removed in v3.0. Use sum() instead." warnings.warn(msg, DeprecationWarning) * Add a warnings filter to `networkx/conftest.py`: warnings.filterwarnings( "ignore", category\=DeprecationWarning, message\= ) * Add a reminder to `doc/developer/deprecations.rst` for the team to remove the deprecated functionality in the future. For example: \* In \`\`utils/misc.py\`\` remove \`\`generate\_unique\_node\`\` and related tests. Note To reviewers: make sure the merge message has a brief description of the change(s) and if the PR closes an issue add, for example, “Closes #123” where 123 is the issue number. Divergence from `upstream main`[#](#divergence-from-upstream-main "Link to this heading") ------------------------------------------------------------------------------------------ If GitHub indicates that the branch of your Pull Request can no longer be merged automatically, merge the main branch into yours: git fetch upstream main git merge upstream/main If any conflicts occur, they need to be fixed before continuing. See which files are in conflict using: git status Which displays a message like: Unmerged paths: (use "git add ..." to mark resolution) both modified: file\_with\_conflict.txt Inside the conflicted file, you’ll find sections like these: <<<<<<< HEAD The way the text looks in your branch \======= The way the text looks in the main branch \>>>>>>> main Choose one version of the text that should be kept, and delete the rest: The way the text looks in your branch Now, add the fixed file: git add file\_with\_conflict.txt Once you’ve fixed all merge conflicts, do: git commit Note Advanced Git users may want to rebase instead of merge, but we squash and merge PRs either way. Guidelines[#](#guidelines "Link to this heading") -------------------------------------------------- * All code should have tests. * All code should be documented, to the same [standard](https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard) as NumPy and SciPy. * All changes are reviewed. Ask on the [mailing list](http://groups.google.com/group/networkx-discuss) if you get no response to your pull request. * Default dependencies are listed in `requirements/default.txt` and extra (i.e., optional) dependencies are listed in `requirements/extra.txt`. We don’t often add new default and extra dependencies. If you are considering adding code that has a dependency, you should first consider adding a gallery example. Typically, new proposed dependencies would first be added as extra dependencies. Extra dependencies should be easy to install on all platforms and widely-used. New default dependencies should be easy to install on all platforms, widely-used in the community, and have demonstrated potential for wide-spread use in NetworkX. * Use the following import conventions: import numpy as np import scipy as sp import matplotlib as mpl import matplotlib.pyplot as plt import pandas as pd import networkx as nx After importing `sp` for `scipy`: import scipy as sp access the relevant scipy subpackages from the top-level `sp` namespace, e.g.: sp.sparse.linalg Instead of `from scipy.sparse import linalg` or `import scipy.sparse.linalg as spla`. For example, many libraries have a `linalg` subpackage: `nx.linalg`, `np.linalg`, `sp.linalg`, `sp.sparse.linalg`. The above import pattern makes the origin of any particular instance of `linalg` explicit. * Use the decorator `not_implemented_for` in `networkx/utils/decorators.py` to designate that a function doesn’t accept ‘directed’, ‘undirected’, ‘multigraph’ or ‘graph’. The first argument of the decorated function should be the graph object to be checked. @nx.not\_implemented\_for("directed", "multigraph") def function\_not\_for\_MultiDiGraph(G, others): \# function not for graphs that are directed \*and\* multigraph pass @nx.not\_implemented\_for("directed") @nx.not\_implemented\_for("multigraph") def function\_only\_for\_Graph(G, others): \# function not for directed graphs \*or\* for multigraphs pass Testing[#](#testing "Link to this heading") -------------------------------------------- `networkx` has an extensive test suite that ensures correct execution on your system. The test suite has to pass before a pull request can be merged, and tests should be added to cover any modifications to the code base. We make use of the [pytest](https://docs.pytest.org/en/latest/) testing framework, with tests located in the various `networkx/submodule/tests` folders. To run all tests: $ PYTHONPATH=. pytest networkx Or the tests for a specific submodule: $ PYTHONPATH=. pytest networkx/readwrite Or tests from a specific file: $ PYTHONPATH=. pytest networkx/readwrite/tests/test\_edgelist.py Or a single test within that file: $ PYTHONPATH=. pytest networkx/readwrite/tests/test\_edgelist.py::test\_parse\_edgelist\_with\_data\_list Use `--doctest-modules` to run doctests. For example, run all tests and all doctests using: $ PYTHONPATH=. pytest --doctest-modules networkx Tests for a module should ideally cover all code in that module, i.e., statement coverage should be at 100%. To measure the test coverage, run: $ PYTHONPATH=. pytest --cov=networkx networkx This will print a report with one line for each file in `networkx`, detailing the test coverage: Name Stmts Miss Branch BrPart Cover \---------------------------------------------------------------------------------- networkx/\_\_init\_\_.py 33 2 2 1 91% networkx/algorithms/\_\_init\_\_.py 114 0 0 0 100% networkx/algorithms/approximation/\_\_init\_\_.py 12 0 0 0 100% networkx/algorithms/approximation/clique.py 42 1 18 1 97% ... ### Adding tests[#](#adding-tests "Link to this heading") If you’re **new to testing**, see existing test files for examples of things to do. **Don’t let the tests keep you from submitting your contribution!** If you’re not sure how to do this or are having trouble, submit your pull request anyway. We will help you create the tests and sort out any kind of problem during code review. ### Image comparison[#](#image-comparison "Link to this heading") To run image comparisons: $ PYTHONPATH=. pytest --mpl --pyargs networkx.drawing The `--mpl` tells `pytest` to use `pytest-mpl` to compare the generated plots with baseline ones stored in `networkx/drawing/tests/baseline`. To add a new test, add a test function to `networkx/drawing/tests` that returns a Matplotlib figure (or any figure object that has a savefig method) and decorate it as follows: @pytest.mark.mpl\_image\_compare def test\_barbell(): fig \= plt.figure() barbell \= nx.barbell\_graph(4, 6) \# make sure to fix any randomness pos \= nx.spring\_layout(barbell, seed\=42) nx.draw(barbell, pos\=pos) return fig Then create a baseline image to compare against later: $ pytest -k test\_barbell --mpl-generate-path=networkx/drawing/tests/baseline Note In order to keep the size of the repository from becoming too large, we prefer to limit the size and number of baseline images we include. And test: $ pytest -k test\_barbell --mpl Documentation[#](#documentation "Link to this heading") -------------------------------------------------------- We use Sphinx for generating the API and reference documentation. Pre-built versions can be found at > [https://networkx.org/](https://networkx.org/) for both the stable and the latest (i.e., development) releases. ### Instructions[#](#instructions "Link to this heading") After installing NetworkX and its dependencies, install the Python packages needed to build the documentation by entering the root directory and executing: pip install \-r requirements/doc.txt Building the example gallery additionally requires the dependencies listed in `requirements/extra.txt` and `requirements/example.txt`: pip install \-r requirements/extra.txt pip install \-r requirements/example.txt To build the HTML documentation, enter `doc/` and execute: make html This will generate a `build/html` subdirectory containing the built documentation. If the dependencies in `extra.txt` and `example.txt` are **not** installed, build the HTML documentation without generating figures by using: make html\-noplot To build the PDF documentation, enter: make latexpdf You will need to have LaTeX installed for this. Note `sphinx` supports many other output formats. Type `make` without any arguments to see all the built-in options. ### Adding examples[#](#adding-examples "Link to this heading") The gallery examples are managed by [sphinx-gallery](https://sphinx-gallery.readthedocs.io/) . The source files for the example gallery are `.py` scripts in `examples/` that generate one or more figures. They are executed automatically by sphinx-gallery when the documentation is built. The output is gathered and assembled into the gallery. Building the example gallery locally requires that the additional dependencies in `requirements/example.txt` be installed in your development environment. You can **add a new** plot by placing a new `.py` file in one of the directories inside the `examples` directory of the repository. See the other examples to get an idea for the format. Note Gallery examples should start with `plot_`, e.g. `plot_new_example.py` General guidelines for making a good gallery plot: * Examples should highlight a single feature/command. * Try to make the example as simple as possible. * Data needed by examples should be included in the same directory and the example script. * Add comments to explain things that aren’t obvious from reading the code. * Describe the feature that you’re showcasing and link to other relevant parts of the documentation. ### Adding References[#](#adding-references "Link to this heading") If you are contributing a new algorithm (or an improvement to a current algorithm), a reference paper or resource should also be provided in the function docstring. For references to published papers, we try to follow the [Chicago Citation Style](https://en.wikipedia.org/wiki/The_Chicago_Manual_of_Style) . The quickest way of generating citation in this style is by searching for the paper on [Google Scholar](https://scholar.google.com/) and clicking on the `cite` button. It will pop up the citation of the paper in multiple formats, and copy the `Chicago` style. We prefer adding DOI links for URLs. If the DOI link resolves to a paywalled version of the article, we prefer adding a link to the arXiv version (if available) or any other publicly accessible copy of the paper. An example of a reference: .. \[1\] Cheong, Se\-Hang, and Yain\-Whar Si. "Force-directed algorithms for schematic drawings and placement: A survey." Information Visualization 19, no. 1 (2020): 65-91. https://doi.org/10.1177%2F1473871618821740 If the resource is uploaded as a PDF/DOCX/PPT on the web (lecture notes, presentations) it is better to use the [wayback machine](https://web.archive.org/) to create a snapshot of the resource and link the internet archive link. The URL of the resource can change, and it creates unreachable links from the documentation. ### Using Math Formulae and Latex Formatting in Documentation[#](#using-math-formulae-and-latex-formatting-in-documentation "Link to this heading") When working with docstrings that contain math symbols or formulae use raw strings (`r"""`) to ensure proper rendering. While LaTeX formatting can improve the appearance of the rendered documentation, it’s best to keep it simple and readable. An example of a math formula: .. math:: Ax \= \\lambda x \\\[Ax = \\lambda x\\\] Some inline math: These are Cheeger's Inequalities for \\d-Regular graphs: $\\frac{d- \\lambda\_2}{2} \\leq h(G) \\leq \\sqrt{2d(d- \\lambda\_2)}$ These are Cheeger’s Inequalities for d-Regular graphs: \\(\\frac{d- \\lambda\_2}{2} \\leq h(G) \\leq \\sqrt{2d(d- \\lambda\_2)}\\) Bugs[#](#bugs "Link to this heading") -------------------------------------- Please [report bugs on GitHub](https://github.com/networkx/networkx/issues) . Policies[#](#policies "Link to this heading") ---------------------------------------------- All interactions with the project are subject to the [NetworkX code of conduct](code_of_conduct.html) . We also follow these policies: * [NetworkX deprecation policy](deprecations.html) * [Python version support](https://numpy.org/neps/nep-0029-deprecation_policy.html "(in NumPy Enhancement Proposals)") On this page --- # Mentored Projects — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Mentored Projects[#](#mentored-projects "Link to this heading") ================================================================ This page maintains a list of mentored project ideas that contributors can work on if they are interested in contributing to the NetworkX project. Feel free to suggest any other idea if you are interested on the [NetworkX GitHub discussions page](https://github.com/networkx/networkx/discussions) These ideas can be used as projects for Google Summer of Code, Outreachy, NumFOCUS Small Development Grants and university course/project credits (if your university allows contribution to open source for credit). Pedagogical Interactive Notebooks for Algorithms Implemented in NetworkX[#](#pedagogical-interactive-notebooks-for-algorithms-implemented-in-networkx "Link to this heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ * Abstract: NetworkX has a [wide variety of algorithms](../reference/algorithms/index.html#algorithms) implemented. Even though the algorithms are well documented, explanations of the ideas behind the algorithms are often missing and we would like to collect these, write Jupyter notebooks to elucidate these ideas and explore the algorithms experimentally, and publish the notebooks at [networkx/notebooks](https://github.com/networkx/notebooks) . The goal is to gives readers a deeper outlook behind standard network science and graph theory algorithms and encourage them to delve further into the topic. * Recommended Skills: Python, Jupyter notebooks, graph algorithms. * Expected Outcome: A collection of Interactive Jupyter notebooks which explain and explore network algorithms to readers and users of NetworkX. For example, see this notebook on [Geometric Generator Models](https://networkx.org/nx-guides/content/generators/geometric.html "(in nx-guides)") * Complexity: Depending on the algorithms you are interested to work on. * Interested Mentors: [@MridulS](https://github.com/MridulS/) , [@rossbar](https://github.com/rossbar/) * Expected time commitment: This project can be either a medium project (~175 hours) or a large project (~350 hours). The contributor is expected to contribute 2-3 pedagogical interactive notebooks for the medium duration project and 4-5 notebooks for the long duration project. Visualization API with Matplotlib[#](#visualization-api-with-matplotlib "Link to this heading") ------------------------------------------------------------------------------------------------ * Abstract: NetworkX has some basic drawing tools that use Matplotlib to render the images. The API hasn’t changed while Matplotlib has changed. Also we have added or are trying to add new features especially with regard to plotting edges. We’d like someone to read a lot about what we offer and also what Matplotlib offers, and come up with a nice way for users to draw graphs flexibly and yet with good defaults. There is little chance just a broad topic could be completed in one summer, but a roadmap and substantial headway on that road is possible. * Recommended Skills: Python, matplotlib experience. * Expected Outcome: A roadmap for a refined API for the matplotlib tools within NetworkX as well as code in the form of PR(s) which implement (part of) that API with tests. * Interested Mentors: [@dschult](https://github.com/dschult/) , [@rossbar](https://github.com/rossbar/) * Expected time commitment: This project will be a full time 10 week project (~350 hrs). Incorporate a Python library for ISMAGs isomorphism calculations[#](#incorporate-a-python-library-for-ismags-isomorphism-calculations "Link to this heading") -------------------------------------------------------------------------------------------------------------------------------------------------------------- * Abstract: A team from Sandia Labs has converted the original java implementation of the ISMAGS isomorphism routines to Python. They have invited us to incorporate that code into NetworkX if we are interested. We’d like someone to learn the ISMAGS code we currently provide, and the code from this new library and figure out what the best combination is to include in NetworkX moving forward. That could be two separate subpackages of tools, or more likely a combination of the two sets of code, or a third incantation that combines good features from each. * Recommended Skills: Python, graph algorithms. * Expected Outcome: A plan for how to best incorporate ISMAGS into NetworkX along with code to do that incorporation. * Interested Mentors: [@dschult](https://github.com/dschult/) , [@rossbar](https://github.com/rossbar/) * Expected time commitment: This project will be a full time 10 week project (~350 hrs). Centrality Atlas[#](#centrality-atlas "Link to this heading") -------------------------------------------------------------- * Abstract: The goal of this project would be to produce a comprehensive review of network centrality measures. Centrality is a central concept in network science and has many applications across domains. NetworkX provides many functions for measuring various types of [network centrality](../reference/algorithms/centrality.html) . The individual centrality functions are typically well-described by their docstrings (though there’s always room for improvement!); however, there currently is no big-picture overview of centrality. Furthermore, many of the centrality measures are closely related, but there is no documentation that describes these relationships. * Recommended Skills: Python, literature review, technical writing * Expected Outcome: An executable document that provides an overview and applications of network centrality measures. Potential outputs include (but are not limited to): an article for `nx-guides` (see above) and/or an example gallery for centrality measures. * Interested Mentors: [@dschult](https://github.com/dschult/) , [@rossbar](https://github.com/rossbar/) * Expected time commitment: Variable, though a high-quality review article would be expected to take several months of dedicated research (~350 hours). Completed Projects[#](#completed-projects "Link to this heading") ================================================================== * [Revisiting and expanding nx-parallel](https://github.com/Schefflera-Arboricola/blogs/tree/main/networkx/GSoC24) * Program: Google Summer of Code 2024 * Contributor: [@Schefflera-Arboricola](https://github.com/Schefflera-Arboricola) * Link to Proposal: [GSoC 2024: Revisiting and expanding nx-parallel](https://github.com/networkx/archive/blob/main/proposals-gsoc/GSoC-2024-Revisiting-and-expanding-nx-parallel.pdf) * [VF2++ algorithm for graph isomorphism](https://github.com/networkx/networkx/pull/5788) * Program: Google Summer of Code 2022 * Contributor: [@kpetridis24](https://github.com/kpetridis24/) * Link to Proposal: [GSoC 2022: VF2++ Algorithm](https://github.com/networkx/archive/blob/main/proposals-gsoc/GSoC-2022-VF2plusplus-isomorphism.pdf) * [Louvain community detection algorithm](https://github.com/networkx/networkx/pull/4929) * Program: Google Summer of Code 2021 * Contributor: [@z3y50n](https://github.com/z3y50n/) * Link to Proposal: [GSoC 2021: Community Detection Algorithms](https://github.com/networkx/archive/blob/main/proposals-gsoc/GSoC-2021-Community-Detection-Algorithms.pdf) * [Asadpour algorithm for directed travelling salesman problem](https://github.com/networkx/networkx/pull/4740) * Program: Google Summer of Code 2021 * Contributor: [@mjschwenne](https://github.com/mjschwenne/) * Link to Proposal: [GSoC 2021: Asadpour algorithm](https://github.com/networkx/archive/blob/main/proposals-gsoc/GSoC-2021-Asadpour-Asymmetric-Traveling%20Salesman-Problem.pdf) * Pedagogical notebook: [Directed acyclic graphs and topological sort](https://github.com/networkx/nx-guides/pull/44) * Program: Google Summer of Code 2021 * Contributor: [@vdshk](https://github.com/vdshk) * Pedagogical notebooks: [Graph assortativity](https://github.com/networkx/nx-guides/pull/42) & [Network flow analysis and Dinitz algorithm](https://github.com/networkx/nx-guides/pull/46) * Program: Google Summer of Code 2021 * Contributor: [@harshal-dupare](https://github.com/harshal-dupare/) * Add On system for NetworkX: [NetworkX-Metis](https://github.com/networkx/networkx-metis) * Program: Google Summer of Code 2015 * Contributor: [@OrkoHunter](https://github.com/OrkoHunter/) * Link to Proposal: [GSoC 2015: Add On System for NetworkX](https://github.com/networkx/archive/blob/main/proposals-gsoc/GSoC-2015-Add-on-system-for-NetworkX.md) * [NetworkX 2.0 API](https://networkx.org/documentation/latest/release/migration_guide_from_1.x_to_2.0.html) * Program: Google Summer of Code 2015 * Contributor: [@MridulS](https://github.com/MridulS/) * Link to Proposal: [GSoC 2015: NetworkX 2.0 API](https://github.com/networkx/archive/blob/main/proposals-gsoc/GSoC-2015-NetworkX-2.0-api.md) On this page --- # New Contributor FAQ — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") New Contributor FAQ[#](#new-contributor-faq "Link to this heading") ==================================================================== A collection of frequently-asked questions by newcomers to open-source development and first-time contributors to NetworkX. Q: I’m new to open source and would like to contribute to NetworkX. How do I get started?[#](#q-i-m-new-to-open-source-and-would-like-to-contribute-to-networkx-how-do-i-get-started "Link to this heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- To contribute to NetworkX, you will need three things: > 1. The source code > > 2. A development environment > > 3. An idea of what you’d like to contribute > Steps 1 & 2 are covered extensively in [Development Workflow](contribute.html#dev-workflow) . There is no generic answer for step 3. There are many ways that NetworkX can be improved, from adding new algorithms, improving existing algorithms, improving the test suite (e.g. increasing test coverage), and improving the documentation. The “best” way to find a place to start is to follow your own personal interests! That said, a few places to check for ideas on where to get started: > * [The issue tracker](https://github.com/networkx/networkx/issues) > lists known bugs and feature requests. Of particular interest for first-time contributors are issues that have been tagged with the [Good First Issue](https://github.com/networkx/networkx/issues?q=is%3Aopen+is%3Aissue+label%3A%22Good+First+Issue%22) > or [Sprint](https://github.com/networkx/networkx/issues?q=is%3Aopen+is%3Aissue+label%3ASprint) > labels. > > * The [Algorithms discussion](https://github.com/networkx/networkx/discussions/categories/algorithms) > includes a listing of algorithms that users would like to have but that are not yet included in NetworkX. > Q: I’ve found an issue I’m interested in, can I have it assigned to me?[#](#q-i-ve-found-an-issue-i-m-interested-in-can-i-have-it-assigned-to-me "Link to this heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- NetworkX doesn’t typically assign issues to contributors. If you find an issue or feature request on the issue tracker that you’d like to work on, you should first check the issue thread to see if there are any linked pull requests. If not, then feel free to open a new PR to address the issue - no need to ask for permission - and don’t forget to reference the issue number in the PR comments so that others know you are now working on it! Q: How do I contribute an example to the Gallery?[#](#q-how-do-i-contribute-an-example-to-the-gallery "Link to this heading") ------------------------------------------------------------------------------------------------------------------------------ The example gallery is great place to contribute, particularly if you have an interesting application or visualization that uses NetworkX. The gallery is generated using [sphinx-gallery](https://sphinx-gallery.github.io/stable/index.html "(in Sphinx-Gallery v0.18.0)") from Python scripts stored in the `examples/` directory. For instance, let’s say I’d like to contribute an example of visualizing a [`complete graph`](../reference/generated/networkx.generators.classic.complete_graph.html#networkx.generators.classic.complete_graph "networkx.generators.classic.complete_graph") using a [`circular layout`](../reference/generated/networkx.drawing.layout.circular_layout.html#networkx.drawing.layout.circular_layout "networkx.drawing.layout.circular_layout") . Assuming you have already followed the procedure for [setting up a development environment](contribute.html#dev-workflow) , start by creating a new branch: git checkout \-b complete-graph-circular-layout-example Note It’s generally a good idea to give your branch a descriptive name so that it’s easy to remember what you are working on. Now you can begin work on your example. Sticking with the circular layout idea, you might create a file in `examples/drawing` called `plot_circular_layout.py` with the following contents: import networkx as nx import matplotlib.pyplot as plt G \= nx.complete\_graph(10) \# A complete graph with 10 nodes nx.draw\_networkx(G, pos\=nx.circular\_layout(G)) Note It may not be clear where exactly an example belongs. Our circular layout example is very simple, so perhaps it belongs in `examples/basic`. It would also make sense for it to be in `examples/drawing` since it deals with visualization. Don’t worry if you’re not sure: questions like this will be resolved during the review process. At this point, your contribution is ready to be reviewed. You can make the changes on your `complete-graph-circular-layout-example` branch visible to other NetworkX developers by [creating a pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request) . See also The [developer guide](contribute.html#dev-workflow) has more details on creating pull requests. Q: I want to work on a specific function. How do I find it in the source code?[#](#q-i-want-to-work-on-a-specific-function-how-do-i-find-it-in-the-source-code "Link to this heading") --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Assuming you have followed the instructions for [setting up the development workflow](contribute.html#dev-workflow) , there are several ways of determining where the in the **source code** a particular function or class is defined. For example, let’s say you are interested in making a change to the [`kamada_kawai_layout`](../reference/generated/networkx.drawing.layout.kamada_kawai_layout.html#networkx.drawing.layout.kamada_kawai_layout "networkx.drawing.layout.kamada_kawai_layout") function, so you need to know where it is defined. In an IPython terminal, you can use `?` — the source file is listed in the `File:` field: In \[1\]: import networkx as nx In \[2\]: nx.kamada\_kawai\_layout? Signature: Docstring: File: ~/networkx/networkx/drawing/layout.py Type: function Command line utilities like `grep` or `git grep` are also very useful. For example, from the NetworkX source directory: $ grep \-r "def kamada\_kawai\_layout" . ./networkx/drawing/layout.py:def kamada\_kawai\_layout( Q: What is the policy for deciding whether to include a new algorithm?[#](#q-what-is-the-policy-for-deciding-whether-to-include-a-new-algorithm "Link to this heading") ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ There is no official policy setting explicit inclusion criteria for new algorithms in NetworkX. New algorithms are more likely to be included if they have been published and are cited by others. More important than number of citations is how well proposed additions fit the project [Mission and Values](values.html#mission-and-values) . Testing is also an important factor in determining whether algorithms should be included. Proposals that include thorough tests which illustrate expected behavior are much easier to review, and therefore likely to progress more rapidly. Note _Thorough_ does not mean _exhaustive_. The quality of unit tests is much more important than quantity. Thorough tests should address questions like: * Does the algorithm support different graph types (undirected, directed, multigraphs)? * How does the algorithm behave with disconnected inputs and graphs which contain self-loops? * Are there explicit test cases outlined in the literature which can be incorporated in the test suite? On this page --- # Core Developer Guide — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Core Developer Guide[#](#core-developer-guide "Link to this heading") ====================================================================== As a core developer, you should continue making pull requests in accordance with the [Contributor Guide](contribute.html#contributor-guide) . You are responsible for shepherding other contributors through the review process. You should be familiar with our [Mission and Values](values.html#mission-and-values) . You also have the ability to merge or approve other contributors’ pull requests. Much like nuclear launch keys, it is a shared power: you must merge _only after_ another core developer has approved the pull request, _and_ after you yourself have carefully reviewed it. (See [Reviewing](#reviewing) and especially [Merge Only Changes You Understand](#merge-only-changes-you-understand) below.) To ensure a clean git history, use GitHub’s [Squash and Merge](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/merging-a-pull-request#merging-a-pull-request-on-github) feature to merge, unless you have a good reason not to do so. Reviewing[#](#reviewing "Link to this heading") ------------------------------------------------ ### How to Conduct A Good Review[#](#how-to-conduct-a-good-review "Link to this heading") _Always_ be kind to contributors. Nearly all of NetworkX is volunteer work, for which we are tremendously grateful. Provide constructive criticism on ideas and implementations, and remind yourself of how it felt when your own work was being evaluated as a novice. NetworkX strongly values mentorship in code review. New users often need more handholding, having little to no git experience. Repeat yourself liberally, and, if you don’t recognize a contributor, point them to our development guide, or other GitHub workflow tutorials around the web. Do not assume that they know how GitHub works (e.g., many don’t realize that adding a commit automatically updates a pull request). Gentle, polite, kind encouragement can make the difference between a new core developer and an abandoned pull request. When reviewing, focus on the following: 1. **API:** The API is what users see when they first use NetworkX. APIs are difficult to change once released, so should be simple, [functional](https://en.wikipedia.org/wiki/Functional_programming) (i.e. not carry state), consistent with other parts of the library, and should avoid modifying input variables. Please familiarize yourself with the project’s [Policy](deprecations.html#deprecation-policy) . 2. **Documentation:** Any new feature should have a gallery example that not only illustrates but explains it. 3. **The algorithm:** You should understand the code being modified or added before approving it. (See [Merge Only Changes You Understand](#merge-only-changes-you-understand) below.) Implementations should do what they claim, and be simple, readable, and efficient. 4. **Tests:** All contributions to the library _must_ be tested, and each added line of code should be covered by at least one test. Good tests not only execute the code, but explores corner cases. It is tempting not to review tests, but please do so. Other changes may be _nitpicky_: spelling mistakes, formatting, etc. Do not ask contributors to make these changes, and instead make the changes by [pushing to their branch](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/committing-changes-to-a-pull-request-branch-created-from-a-fork) , or using GitHub’s [suggestion](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/commenting-on-a-pull-request) [feature](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/incorporating-feedback-in-your-pull-request) . (The latter is preferred because it gives the contributor a choice in whether to accept the changes.) Our default merge policy is to squash all PR commits into a single commit. Users who wish to bring the latest changes from `main` into their branch should be advised to merge, not to rebase. Even when merge conflicts arise, don’t ask for a rebase unless you know that a contributor is experienced with git. Instead, rebase the branch yourself, force-push to their branch, and advise the contributor on how to force-pull. If the contributor is no longer active, you may take over their branch by submitting a new pull request and closing the original. In doing so, ensure you communicate that you are not throwing the contributor’s work away! You should use GitHub’s `Co-authored-by:` keyword for commit messages to credit the original contributor. Please add a note to a pull request after you push new changes; GitHub may not send out notifications for these. ### Merge Only Changes You Understand[#](#merge-only-changes-you-understand "Link to this heading") _Long-term maintainability_ is an important concern. Code doesn’t merely have to _work_, but should be _understood_ by multiple core developers. Changes will have to be made in the future, and the original contributor may have moved on. Therefore, _do not merge a code change unless you understand it_. Ask for help freely: we have a long history of consulting community members, or even external developers, for added insight where needed, and see this as a great learning opportunity. While we collectively “own” any patches (and bugs!) that become part of the code base, you are vouching for changes you merge. Please take that responsibility seriously. Closing issues and pull requests[#](#closing-issues-and-pull-requests "Link to this heading") ---------------------------------------------------------------------------------------------- Sometimes, an issue must be closed that was not fully resolved. This can be for a number of reasons: * the person behind the original post has not responded to calls for clarification, and none of the core developers have been able to reproduce their issue; * fixing the issue is difficult, and it is deemed too niche a use case to devote sustained effort or prioritize over other issues; or * the use case or feature request is something that core developers feel does not belong in NetworkX, among others. Similarly, pull requests sometimes need to be closed without merging, because: * the pull request implements a niche feature that we consider not worth the added maintenance burden; * the pull request implements a useful feature, but requires significant effort to bring up to NetworkX’s standards, and the original contributor has moved on, and no other developer can be found to make the necessary changes; or * the pull request makes changes that do not align with our values, such as increasing the code complexity of a function significantly to implement a marginal speedup, among others. All these may be valid reasons for closing, but we must be wary not to alienate contributors by closing an issue or pull request without an explanation. When closing, your message should: * explain clearly how the decision was made to close. This is particularly important when the decision was made in a community meeting, which does not have as visible a record as the comments thread on the issue itself; * thank the contributor(s) for their work; and * provide a clear path for the contributor or anyone else to appeal the decision. These points help ensure that all contributors feel welcome and empowered to keep contributing, regardless of the outcome of past contributions. Further resources[#](#further-resources "Link to this heading") ---------------------------------------------------------------- As a core member, you should be familiar with community and developer resources such as: * Our [Contributor Guide](contribute.html#contributor-guide) * Our [Code of Conduct](code_of_conduct.html#code-of-conduct) * [PEP8](https://www.python.org/dev/peps/pep-0008/) for Python style * [PEP257](https://www.python.org/dev/peps/pep-0257/) and the [NumPy documentation guide](https://numpy.org/doc/stable/docs/howto_document.html) for docstrings. (NumPy docstrings are a superset of PEP257. You should read both.) * The NetworkX [tag on StackOverflow](https://stackoverflow.com/questions/tagged/networkx) * Our [mailing list](http://groups.google.com/group/networkx-discuss/) You are not required to monitor all of the social resources. On this page --- # Node Assortativity Coefficients and Correlation Measures — NetworkX Notebooks [Skip to main content](#main-content) Back to top Ctrl+K [![NetworkX Notebooks - Home](../../../_static/networkx_banner.svg) ![NetworkX Notebooks - Home](../../../_static/networkx_banner.svg)](../../../index.html) * [GitHub](https://github.com/networkx/nx-guides/ "GitHub") Search Ctrl+K * [![Binder logo](../../../_static/images/logo_binder.svg)Binder](https://mybinder.org/v2/gh/networkx/nx-guides/main?urlpath=tree/site/content/algorithms/assortativity/correlation.md "Launch on Binder") * [Repository](https://github.com/networkx/nx-guides "Source repository") * [Suggest edit](https://github.com/networkx/nx-guides/edit/main/site/content/algorithms/assortativity/correlation.md "Suggest edit") * [Open issue](https://github.com/networkx/nx-guides/issues/new?title=Issue%20on%20page%20%2Fcontent/algorithms/assortativity/correlation.html&body=Your%20issue%20content%20here. "Open an issue") * [.ipynb](../../../_sources/content/algorithms/assortativity/correlation.ipynb "Download notebook file") * [.md](../../../_sources/content/algorithms/assortativity/correlation.md "Download source file") * .pdf Node Assortativity Coefficients and Correlation Measures ======================================================== Contents -------- Node Assortativity Coefficients and Correlation Measures[#](#node-assortativity-coefficients-and-correlation-measures "Link to this heading") ============================================================================================================================================== In this tutorial, we will explore the theory of assortativity [\[1\]](#id5) and its measures. We’ll focus on assortativity measures available in NetworkX at [`algorithms/assortativity/correlation.py`](https://github.com/networkx/networkx/blob/main/networkx/algorithms/assortativity/correlation.py) : * Attribute assortativity * Numeric assortativity * Degree assortativity as well as mixing matrices, which are closely related to assortativity measures. Import packages[#](#import-packages "Link to this heading") ------------------------------------------------------------ import networkx as nx import matplotlib.pyplot as plt import pickle import copy import random import warnings %matplotlib inline Assortativity[#](#assortativity "Link to this heading") -------------------------------------------------------- Assortativity in a network refers to the tendency of nodes to connect with other ‘similar’ nodes over ‘dissimilar’ nodes. Here we say that two nodes are ‘similar’ with respect to a property if they have the same value of that property. Properties can be any structural properties like the degree of a node to other properties like weight, or capacity. Based on these properties we can have a different measure of assortativity for the network. On the other hand, we can also have disassortativity, in which case nodes tend to connect to dissimilar nodes over similar nodes. ### Assortativity coefficients[#](#assortativity-coefficients "Link to this heading") Let’s say we have a network \\(N\\), \\(N = (V, E)\\) where \\(V\\) is the set of nodes in the network and \\(E\\) is the set of edges/directed edges in the network. In addition, \\(P(v)\\) represents a property for each node \\(v\\). #### Mixing matrix[#](#mixing-matrix "Link to this heading") Let the property \\(P(v)\\) take \\(P\[0\],P\[1\],...P\[k-1\]\\) distinct values on the network, then the **mixing matrix** is matrix \\(M\\) such that \\(M\[i\]\[j\]\\) represents the number of edges from nodes with property \\(P\[i\]\\) to \\(P\[j\]\\). We can normalize mixing matrix by diving by total number of ordered edges i.e. \\( e = \\frac{M}{|E|}\\). Now define, \\(a\[i\]=\\) proportion of edges \\((u,v)\\) such that \\(P(u)=P\[i\]\\) \\\[ a\[i\] = \\sum\\limits\_{j}e\[i\]\[j\] \\\] \\(b\[i\]=\\) proportion of edges \\((u,v)\\) such that \\(P(v)=P\[i\]\\) \\\[ b\[i\] = \\sum\\limits\_{j}e\[j\]\[i\]\\\] in Python code it would look something like `a = e.sum(axis=0)` and `b = e.sum(axis=1)` Finally, let \\(\\sigma\_a\\) and \\(\\sigma\_b\\) represent the standard deviation of \\(\\{\\ P\[i\]\\cdot a\[i\]\\ |\\ i \\in 0...k-1\\}\\) and \\(\\{ P\[i\]\\cdot b\[i\]\\ |\\ i \\in 0...k-1\\}\\) respectively. Then we can define the assortativity coefficient for this property based on the Pearson correlation coefficient. #### Attribute Assortativity Coefficient[#](#attribute-assortativity-coefficient "Link to this heading") Here the property \\(P(v)\\) is a nominal property assigned to each node. As defined above we calculate the normalized mixing matrix \\(e\\) and from that we define the attribute assortativity coefficient [\[2\]](#id6) as below. From here onwards we will use subscript notation to denote indexing, for eg. \\(P\_i = P\[i\]\\) and \\(e\_{ij} = e\[i\]\[j\]\\) \\\[ r = \\frac{\\sum\\limits\_{i}e\_{ii} - \\sum\\limits\_{i}a\_{i}b\_{i}}{1-\\sum\\limits\_{i}a\_{i}b\_{i}} = \\frac{Trace(e) - ||e^2||}{1-||e^2||}\\\] It is implemented as `attribute_assortativity_coefficient`. #### Numeric Assortativity Coefficient[#](#numeric-assortativity-coefficient "Link to this heading") Here the property \\(P(v)\\) is a numerical property assigned to each node and the definition of the normalized mixing matrix \\(e\\), \\(\\sigma\_a\\), and \\(\\sigma\_b\\) are same as above. From these we define numeric assortativity coefficient [\[2\]](#id6) as below. \\\[ r = \\frac{\\sum\\limits\_{i,j}P\_i P\_j(e\_{ij} -a\_i b\_j)}{\\sigma\_a\\sigma\_b} \\\] It is implemented as `numeric_assortativity_coefficient`. #### Degree Assortativity Coefficient[#](#degree-assortativity-coefficient "Link to this heading") When it comes to measuring degree assortativity for directed networks we have more options compared to assortativity w.r.t a property because we have 2 types of degrees, namely in-degree and out-degree. Based on the 2 types of degrees we can measure \\(2 \\times 2 =4\\) different types of degree assortativity [\[3\]](#id7) : 1. r(in,in) : Measures tendency of having a directed edge (u,v) such that, in-degree(u) = in-degree(v). 2. r(in,out) : Measures tendency of having a directed edge (u,v) such that, in-degree(u) = out-degree(v). 3. r(out,in) : Measures tendency of having a directed edge (u,v) such that, out-degree(u) = in-degree(v). 4. r(out,out) : Measures tendency of having a directed edge (u,v) such that, out-degree(u) = out-degree(v). Note: If the network is undirected all the 4 types of degree assortativity are the same. To define the degree assortativity coefficient for all 4 types we need slight modification in the definition of \\(P\[i\]\\) and \\(e\\), and the definations of \\(\\sigma\_a\\) and \\(\\sigma\_b\\) remain the same. Let \\(x,y \\in \\{in,out\\}\\). The property \\(P(\\cdot)\\) takes distinct values from the union of the values taken by \\(x\\)\-degree\\((\\cdot)\\) and \\(y\\)\-degree\\((\\cdot)\\), and \\(e\_{i,j}\\) is the proportion of directed edges \\((u,v)\\) with \\(x\\)\-degree\\((u) = P\_i\\) and \\(y\\)\-degree\\((v) = P\_j\\). \\\[ r(x,y) = \\frac{\\sum\\limits\_{i,j}P\_i P\_j(e\_{ij} -a\_i b\_j)}{\\sigma\_a\\sigma\_b} \\\] It is implemented as `degree_assortativity_coefficient` and `degree_pearson_correlation_coefficient`. The latter function uses `scipy.stats.pearsonr` to calculate the assortativity coefficient which makes it potentally faster. Assortativity Example[#](#assortativity-example "Link to this heading") ------------------------------------------------------------------------ Illustrating how value of assortativity changes gname \= "g2" G \= nx.read\_graphml(f"data/{gname}.graphml") with open(f"data/pos\_{gname}", "rb") as fp: pos \= pickle.load(fp) fig, axes \= plt.subplots(4, 2, figsize\=(20, 20)) \# assign colors and labels to nodes based on their 'cluster' and 'num\_prop' property node\_colors \= \["orange" if G.nodes\[u\]\["cluster"\] \== "K5" else "cyan" for u in G.nodes\] node\_labels \= {u: G.nodes\[u\]\["num\_prop"\] for u in G.nodes} for i in range(8): g \= nx.read\_graphml(f"data/{gname}\_{i}.graphml") \# calculating the assortativity coefficients wrt different proeprties cr \= nx.attribute\_assortativity\_coefficient(g, "cluster") r\_in\_out \= nx.degree\_assortativity\_coefficient(g, x\="in", y\="out") nr \= nx.numeric\_assortativity\_coefficient(g, "num\_prop") \# drawing the network nx.draw\_networkx\_nodes( g, pos\=pos, node\_size\=300, ax\=axes\[i // 2\]\[i % 2\], node\_color\=node\_colors ) nx.draw\_networkx\_labels(g, pos\=pos, labels\=node\_labels, ax\=axes\[i // 2\]\[i % 2\]) nx.draw\_networkx\_edges(g, pos\=pos, ax\=axes\[i // 2\]\[i % 2\], edge\_color\="0.7") axes\[i // 2\]\[i % 2\].set\_title( f"Attribute assortativity coefficient = {cr:.3}\\nNumeric assortativity coefficient = {nr:.3}\\nr(in,out) = {r\_in\_out:.3}", size\=15, ) fig.tight\_layout() /home/circleci/repo/venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/correlation.py:302: RuntimeWarning: invalid value encountered in scalar divide return float((xy \* (M - ab)).sum() / np.sqrt(vara \* varb)) ![../../../_images/317b87d9c8c11163902a5f5a78c8145c7f69e182827d26c4166619a7d63940ca.png](../../../_images/317b87d9c8c11163902a5f5a78c8145c7f69e182827d26c4166619a7d63940ca.png) Nodes are colored by the `cluster` property and labeled by `num_prop` property. We can observe that the initial network on the left side is completely assortative and its complement on right side is completely disassortative. As we add edges between nodes of different (similar) attributes in the assortative (disassortative) network, the network tends to a non-assortative network and value of both the assortativity coefficients tends to \\(0\\). The parameter `nodes` in `attribute_assortativity_coefficient` and `numeric_assortativity_coefficient` specifies the nodes whose edges are to be considered in the mixing matrix calculation. That is to say, if \\((u,v)\\) is a directed edge then the edge \\((u,v)\\) will be used in mixing matrix calculation if \\(u\\) is in `nodes`. For the undirected case, it’s considered if atleast one of the \\(u,v\\) in in `nodes`. The `nodes` parameter is interpreted differently in `degree_assortativity_coefficient` and `degree_pearson_correlation_coefficient`, where it specifies the nodes forming a subgraph whose edges are considered in the mixing matrix calculation. \# list of nodes to consider for the i'th network in the example \# Note: passing 'None' means to consider all the nodes nodes\_list \= \[\ None,\ \[str(i) for i in range(3)\],\ \[str(i) for i in range(4)\],\ \[str(i) for i in range(5)\],\ \[str(i) for i in range(4, 8)\],\ \[str(i) for i in range(5, 10)\],\ \] fig, axes \= plt.subplots(3, 2, figsize\=(20, 16)) def color\_node(u, nodes): """Utility function to give the color of a node based on its attribute""" if u not in nodes: return "0.85" if G.nodes\[u\]\["cluster"\] \== "K5": return "orange" else: return "cyan" \# adding a edge to show edge cases G.add\_edge("4", "5") for nodes, ax in zip(nodes\_list, axes.ravel()): \# calculating the value of assortativity cr \= nx.attribute\_assortativity\_coefficient(G, "cluster", nodes\=nodes) nr \= nx.numeric\_assortativity\_coefficient(G, "num\_prop", nodes\=nodes) \# drawing network ax.set\_title( f"Attribute assortativity coefficient: {cr:.3}\\nNumeric assortativity coefficient: {nr:.3}\\nNodes = {nodes}", size\=15, ) if nodes is None: nodes \= \[u for u in G.nodes()\] node\_colors \= \[color\_node(u, nodes) for u in G.nodes\] nx.draw\_networkx\_nodes(G, pos\=pos, node\_size\=450, ax\=ax, node\_color\=node\_colors) nx.draw\_networkx\_labels(G, pos, labels\={u: u for u in G.nodes}, font\_size\=15, ax\=ax) nx.draw\_networkx\_edges( G, pos\=pos, edgelist\=\[(u, v) for u, v in G.edges if u in nodes\], ax\=ax, edge\_color\="0.3", ) fig.tight\_layout() /home/circleci/repo/venv/lib/python3.12/site-packages/networkx/algorithms/assortativity/correlation.py:282: RuntimeWarning: invalid value encountered in scalar divide r = (t - s) / (1 - s) ![../../../_images/0986c3f60dd99208c72561ec1bf455628097e2e68b18ca0c3f7f5cb7b0c2238b.png](../../../_images/0986c3f60dd99208c72561ec1bf455628097e2e68b18ca0c3f7f5cb7b0c2238b.png) In the above plots only the nodes which are considered are colored and rest are grayed out and only the edges which are considerd in the assortativity calculation are drawn. References[#](#references "Link to this heading") -------------------------------------------------- Contents --- # Software for Complex Networks — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Software for Complex Networks[#](#software-for-complex-networks "Link to this heading") ======================================================================================== Release: 3.4.2 Date: Oct 21, 2024 NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. It provides: * tools for the study of the structure and dynamics of social, biological, and infrastructure networks; * a standard programming interface and graph implementation that is suitable for many applications; * a rapid development environment for collaborative, multidisciplinary projects; * support for algorithm acceleration and additional features through third-party backends; * an interface to existing numerical algorithms and code written in C, C++, and FORTRAN; and * the ability to painlessly work with large nonstandard data sets. With NetworkX you can load and store networks in standard and nonstandard data formats, generate many types of random and classic networks, analyze network structure, build network models, design new network algorithms, draw networks, and much more. Citing[#](#citing "Link to this heading") ------------------------------------------ To cite NetworkX please use the following publication: Aric A. Hagberg, Daniel A. Schult and Pieter J. Swart, [“Exploring network structure, dynamics, and function using NetworkX”](http://conference.scipy.org.s3-website-us-east-1.amazonaws.com/proceedings/scipy2008/paper_2/) , in [Proceedings of the 7th Python in Science Conference (SciPy2008)](http://conference.scipy.org.s3-website-us-east-1.amazonaws.com/proceedings/scipy2008/index.html) , Gäel Varoquaux, Travis Vaught, and Jarrod Millman (Eds), (Pasadena, CA USA), pp. 11–15, Aug 2008 [PDF](http://conference.scipy.org.s3-website-us-east-1.amazonaws.com/proceedings/scipy2008/paper_2/full_text.pdf) [BibTeX](http://conference.scipy.org.s3-website-us-east-1.amazonaws.com/proceedings/scipy2008/paper_2/reference.bib) Audience[#](#audience "Link to this heading") ---------------------------------------------- The audience for NetworkX includes mathematicians, physicists, biologists, computer scientists, and social scientists. Good reviews of the science of complex networks are presented in Albert and Barabási [\[BA02\]](#ba02) , Newman [\[Newman03\]](#newman03) , and Dorogovtsev and Mendes [\[DM03\]](#dm03) . See also the classic texts [\[Bollobas01\]](#bollobas01) , [\[Diestel97\]](#diestel97) and [\[West01\]](#west01) for graph theoretic results and terminology. For basic graph algorithms, we recommend the texts of Sedgewick (e.g., [\[Sedgewick01\]](#sedgewick01) and [\[Sedgewick02\]](#sedgewick02) ) and the survey of Brandes and Erlebach [\[BE05\]](#be05) . Python[#](#python "Link to this heading") ------------------------------------------ Python is a powerful programming language that allows simple and flexible representations of networks as well as clear and concise expressions of network algorithms. Python has a vibrant and growing ecosystem of packages that NetworkX uses to provide more features such as numerical linear algebra and drawing. In order to make the most out of NetworkX you will want to know how to write basic programs in Python. Among the many guides to Python, we recommend the [Python documentation](https://docs.python.org/3/) and the text by Alex Martelli [\[Martelli03\]](#martelli03) . License[#](#license "Link to this heading") -------------------------------------------- NetworkX is distributed with the 3-clause BSD license. Copyright (C) 2004\-2024, NetworkX Developers Aric Hagberg Dan Schult Pieter Swart All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: \* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. \* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. \* Neither the name of the NetworkX Developers nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Bibliography[#](#bibliography "Link to this heading") ------------------------------------------------------ \[[BA02](#id1)\ \] R. Albert and A.-L. Barabási, “Statistical mechanics of complex networks”, Reviews of Modern Physics, 74, pp. 47-97, 2002. [https://arxiv.org/abs/cond-mat/0106096](https://arxiv.org/abs/cond-mat/0106096) \[[Bollobas01](#id4)\ \] B. Bollobás, “Random Graphs”, Second Edition, Cambridge University Press, 2001. \[[BE05](#id9)\ \] U. Brandes and T. Erlebach, “Network Analysis: Methodological Foundations”, Lecture Notes in Computer Science, Volume 3418, Springer-Verlag, 2005. \[[Diestel97](#id5)\ \] R. Diestel, “Graph Theory”, Springer-Verlag, 1997. [http://diestel-graph-theory.com/index.html](http://diestel-graph-theory.com/index.html) \[[DM03](#id3)\ \] S.N. Dorogovtsev and J.F.F. Mendes, “Evolution of Networks”, Oxford University Press, 2003. \[[Martelli03](#id10)\ \] A. Martelli, “Python in a Nutshell”, O’Reilly Media Inc, 2003. \[[Newman03](#id2)\ \] M.E.J. Newman, “The Structure and Function of Complex Networks”, SIAM Review, 45, pp. 167-256, 2003. [http://epubs.siam.org/doi/abs/10.1137/S003614450342480](http://epubs.siam.org/doi/abs/10.1137/S003614450342480) \[[Sedgewick02](#id8)\ \] R. Sedgewick, “Algorithms in C: Parts 1-4: Fundamentals, Data Structure, Sorting, Searching”, Addison Wesley Professional, 3rd ed., 2002. \[[Sedgewick01](#id7)\ \] R. Sedgewick, “Algorithms in C, Part 5: Graph Algorithms”, Addison Wesley Professional, 3rd ed., 2001. \[[West01](#id6)\ \] D. B. West, “Introduction to Graph Theory”, Prentice Hall, 2nd ed., 2001. On this page --- # NetworkX 3.4.2 — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NetworkX 3.4.2[#](#networkx-3-4-2 "Link to this heading") ========================================================== Release date: 21 October 2024 Supports Python 3.10, 3.11, 3.12, and 3.13. NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. For more information, please visit our [website](https://networkx.org/) and our [gallery of examples](../auto_examples/index.html#examples-gallery) . Please send comments and questions to the [networkx-discuss mailing list](http://groups.google.com/group/networkx-discuss) . Bug Fixes[#](#bug-fixes "Link to this heading") ------------------------------------------------ * Fix docstrings of dispatchable functions ([#7679](https://github.com/networkx/networkx/pull/7679) ). * Fix draw\_networkx\_nodes return type ([#7685](https://github.com/networkx/networkx/pull/7685) ). Documentation[#](#documentation "Link to this heading") -------------------------------------------------------- * Add disclaimer about LLM driven PRs ([#7683](https://github.com/networkx/networkx/pull/7683) ). Maintenance[#](#maintenance "Link to this heading") ---------------------------------------------------- * Fix doc warnings from recently added docs ([#7682](https://github.com/networkx/networkx/pull/7682) ). Contributors[#](#contributors "Link to this heading") ------------------------------------------------------ 6 authors added to this release (alphabetically): * Dan Schult ([@dschult](https://github.com/dschult) ) * Erik Welch ([@eriknw](https://github.com/eriknw) ) * Jarrod Millman ([@jarrodmillman](https://github.com/jarrodmillman) ) * Kirk Bonney ([@kbonney](https://github.com/kbonney) ) * Mridul Seth ([@MridulS](https://github.com/MridulS) ) * Ross Barnowski ([@rossbar](https://github.com/rossbar) ) 4 reviewers added to this release (alphabetically): * Aditi Juneja ([@Schefflera-Arboricola](https://github.com/Schefflera-Arboricola) ) * Dan Schult ([@dschult](https://github.com/dschult) ) * Jarrod Millman ([@jarrodmillman](https://github.com/jarrodmillman) ) * Matt Schwennesen ([@mjschwenne](https://github.com/mjschwenne) ) \_These lists are automatically generated, and may not be complete or may contain duplicates.\_ On this page --- # Directed Acyclic Graphs & Topological Sort — NetworkX Notebooks [Skip to main content](#main-content) Back to top Ctrl+K [![NetworkX Notebooks - Home](../../../_static/networkx_banner.svg) ![NetworkX Notebooks - Home](../../../_static/networkx_banner.svg)](../../../index.html) * [GitHub](https://github.com/networkx/nx-guides/ "GitHub") Search Ctrl+K * [![Binder logo](../../../_static/images/logo_binder.svg)Binder](https://mybinder.org/v2/gh/networkx/nx-guides/main?urlpath=tree/site/content/algorithms/dag/index.md "Launch on Binder") * [Repository](https://github.com/networkx/nx-guides "Source repository") * [Suggest edit](https://github.com/networkx/nx-guides/edit/main/site/content/algorithms/dag/index.md "Suggest edit") * [Open issue](https://github.com/networkx/nx-guides/issues/new?title=Issue%20on%20page%20%2Fcontent/algorithms/dag/index.html&body=Your%20issue%20content%20here. "Open an issue") * [.ipynb](../../../_sources/content/algorithms/dag/index.ipynb "Download notebook file") * [.md](../../../_sources/content/algorithms/dag/index.md "Download source file") * .pdf Directed Acyclic Graphs & Topological Sort ========================================== Contents -------- Directed Acyclic Graphs & Topological Sort[#](#directed-acyclic-graphs-topological-sort "Link to this heading") ================================================================================================================ In this tutorial, we will explore the algorithms related to a directed acyclic graph (or a “DAG” as it is sometimes called) implemented in NetworkX under [`networkx/algorithms/dag.py`](https://github.com/networkx/networkx/blob/main/networkx/algorithms/dag.py) . First of all, we need to understand what a directed graph is. Import packages[#](#import-packages "Link to this heading") ------------------------------------------------------------ import networkx as nx import matplotlib.pyplot as plt import inspect %matplotlib inline Example: Directed Graphs[#](#example-directed-graphs "Link to this heading") ----------------------------------------------------------------------------- triangle\_graph \= nx.DiGraph(\[(1, 2), (2, 3), (3, 1)\]) nx.draw\_planar( triangle\_graph, with\_labels\=True, node\_size\=1000, node\_color\="#ffff8f", width\=0.8, font\_size\=14, ) ![../../../_images/9cd65356abe2093f66144a2d2f63bb03259053b22f314306245212c03f995648.png](../../../_images/9cd65356abe2093f66144a2d2f63bb03259053b22f314306245212c03f995648.png) ### Definition[#](#definition "Link to this heading") In mathematics, and more specifically in graph theory, a directed graph (or DiGraph) is a graph that is made up of a set of vertices connected by directed edges often called arcs. Edges here have _directionality_, which stands in contrast to undirected graphs where, semantically, edges have no notion of a direction to them. Directed acyclic graphs take this idea further; by being _acyclic_, they have no _cycles_ in them. You will see this idea in action in the examples below. Directed Acyclic Graph[#](#directed-acyclic-graph "Link to this heading") -------------------------------------------------------------------------- ### Example[#](#example "Link to this heading") clothing\_graph \= nx.read\_graphml(f"data/clothing\_graph.graphml") plt.figure(figsize\=(12, 12), dpi\=150) nx.draw\_planar( clothing\_graph, arrowsize\=12, with\_labels\=True, node\_size\=8000, node\_color\="#ffff8f", linewidths\=2.0, width\=1.5, font\_size\=14, ) ![../../../_images/2242067e8a9705d61289088a580a58706045c8e2e8fd03050920fa381331eb7f.png](../../../_images/2242067e8a9705d61289088a580a58706045c8e2e8fd03050920fa381331eb7f.png) Here is a fun example of Professor Bumstead, who has a routine for getting dressed in the morning. By habit, the professor dons certain garments before others (e.g., socks before shoes). Other items may be put on in any order (e.g., socks and pants). A directed edge \\((u, v)\\) in the example indicates that garment \\(u\\) must be donned before garment \\(v\\). In this example, the `clothing_graph` is a DAG. nx.is\_directed\_acyclic\_graph(clothing\_graph) True By contrast, the `triangle_graph` is not a DAG. nx.is\_directed\_acyclic\_graph(triangle\_graph) False This is because the `triangle_graph` has a cycle: nx.find\_cycle(triangle\_graph) \[(1, 2), (2, 3), (3, 1)\] ### Applications[#](#applications "Link to this heading") Directed acyclic graphs representations of partial orderings have many applications in scheduling of systems of tasks with ordering constraints. An important class of problems of this type concern collections of objects that need to be updated, for example, calculating the order of cells of a spreadsheet to update after one of the cells has been changed, or identifying which object files of software to update after its source code has been changed. In these contexts, we use a dependency graph, which is a graph that has a vertex for each object to be updated, and an edge connecting two objects whenever one of them needs to be updated earlier than the other. A cycle in this graph is called a circular dependency, and is generally not allowed, because there would be no way to consistently schedule the tasks involved in the cycle. Dependency graphs without circular dependencies form DAGs. A directed acyclic graph may also be used to represent a network of processing elements. In this representation, data enters a processing element through its incoming edges and leaves the element through its outgoing edges. For instance, in electronic circuit design, static combinational logic blocks can be represented as an acyclic system of logic gates that computes a function of an input, where the input and output of the function are represented as individual bits. ### Definition[#](#id1 "Link to this heading") A directed acyclic graph (“DAG” or “dag”) is a directed graph with no directed cycles. That is, it consists of vertices and edges (also called arcs), with each edge directed from one vertex to another, such that following those directions will never form a closed loop. A directed graph is a DAG if and only if it can be topologically ordered by arranging the vertices as a linear ordering that is consistent with all edge directions. Topological sort[#](#topological-sort "Link to this heading") -------------------------------------------------------------- Let’s now introduce what the topological sort is. ### Example[#](#id2 "Link to this heading") list(nx.topological\_sort(clothing\_graph)) \['undershorts',\ 'shirt',\ 'socks',\ 'watch',\ 'pants',\ 'tie',\ 'belt',\ 'shoes',\ 'jacket'\] ### Applications[#](#id3 "Link to this heading") The canonical application of topological sorting is in scheduling a sequence of jobs or tasks based on their dependencies. The jobs are represented by vertices, and there is an edge from \\(u\\) to \\(v\\) if job \\(u\\) must be completed before job \\(v\\) can be started (for example, when washing clothes, the washing machine must finish before we put the clothes in the dryer). Then, a topological sort gives an order in which to perform the jobs. A closely related application of topological sorting algorithms was first studied in the early 1960s in the context of the PERT technique [\[1\]](#id6) for scheduling in project management. In this application, the vertices of a graph represent the milestones of a project, and the edges represent tasks that must be performed between one milestone and another. Topological sorting forms the basis of linear-time algorithms for finding the critical path of the project, a sequence of milestones and tasks that controls the length of the overall project schedule. In computer science, applications of this type arise in instruction scheduling, ordering of formula cell evaluation when recomputing formula values in spreadsheets, logic synthesis, determining the order of compilation tasks to perform in makefiles, data serialization, and resolving symbol dependencies in linkers. It is also used to decide in which order to load tables with foreign keys in databases. ### Definition[#](#id5 "Link to this heading") A topological sort of a directed acyclic graph \\(G = (V, E)\\) is a linear ordering of all its vertices such that if \\(G\\) contains an edge \\((u, v)\\), then \\(u\\) appears before \\(v\\) in the ordering. It is worth noting that if the graph contains a cycle, then no linear ordering is possible. It is useful to view a topological sort of a graph as an ordering of its vertices along a horizontal line so that all directed edges go from left to right. ### Kahn’s algorithm[#](#kahn-s-algorithm "Link to this heading") NetworkX uses Kahn’s algorithm to perform topological sorting. We will introduce it briefly here. First, find a list of “start nodes” which have no incoming edges and insert them into a set S; at least one such node must exist in a non-empty acyclic graph. Then: L <- Empty list that will contain the sorted elements S <- Set of all nodes with no incoming edge while S is not empty do remove a node N from S add N to L for each node M with an edge E from N to M do remove edge E from the graph if M has no other incoming edges then insert M into S if graph has edges then return error \# graph has at least one cycle else return L \# a topologically sorted order ### NetworkX implementation[#](#networkx-implementation "Link to this heading") Finally, let’s take a look at how the topological sorting is implemented in NetworkX. We can see that Kahn’s algorithm _stratifies_ the graph such that each level contains all the nodes whose dependencies have been satisfied by the nodes in a previous level. In other words, Kahn’s algorithm does something like: * Take all the nodes in the DAG that don’t have any dependencies and put them in list. * “Remove” those nodes from the DAG. * Repeat the process, creating a new list at each step. Thus, topological sorting is reduced to correctly stratifying the graph in this way. This procedure is implemented in the `topological_generations()` function, on which the `topological_sort()` function is based. Let’s see how the `topological_generations()` function is implemented in NetworkX step by step. #### Step 1. Initialize in-degrees.[#](#step-1-initialize-in-degrees "Link to this heading") Since in Kahn’s algorithm we are only interested in the in-degrees of the vertices, in order to preserve the structure of the graph as it is passed in, instead of removing the edges, we will decrease the in-degree of the corresponding vertex. Therefore, we will save these values in a separate _dictionary_ `indegree_map`. indegree\_map \= {v: d for v, d in G.in\_degree() if d \> 0} #### Step 2. Initialize first level.[#](#step-2-initialize-first-level "Link to this heading") At each step of Kahn’s algorithm, we seek out vertices with an in-degree of zero. In preparation for the first loop iteration of the algorithm, we can initialize a list called `zero_indegree` that houses these nodes: zero\_indegree \= \[v for v, d in G.in\_degree() if d \== 0\] #### Step 3. Move from one level to the next.[#](#step-3-move-from-one-level-to-the-next "Link to this heading") Now, we will show how the algorithm moves from one level to the next. Inside the loop, the first generation to be considered (`this_generation`) is the collection of nodes that have zero in-degrees. We process all the vertices of the current level in variable `this_generation` and we store the next level in variable `zero_indegree`. For each vertex inside `this_generation`, we remove all of its outgoing edges. Then, if the input degree of some vertex is zeroed as a result, then we add it to the next level `zero_indegree` and remove it from the `indegree_map` dictionary. After we have processed all of the nodes inside `this_generation`, we can yield it. while zero\_indegree: this\_generation \= zero\_indegree zero\_indegree \= \[\] for node in this\_generation: for child in G.neighbors(node): indegree\_map\[child\] \-= 1 if indegree\_map\[child\] \== 0: zero\_indegree.append(child) del indegree\_map\[child\] yield this\_generation #### Step 4. Check if there is a cycle in the graph.[#](#step-4-check-if-there-is-a-cycle-in-the-graph "Link to this heading") If, after completing the loop there are still vertices in the graph, then there is a cycle in it and the graph is not a DAG. if indegree\_map: raise nx.NetworkXUnfeasible( "Graph contains a cycle or graph changed during iteration" ) #### Addendum: Topological sort works on multigraphs as well.[#](#addendum-topological-sort-works-on-multigraphs-as-well "Link to this heading") This is possible to do by slightly modifying the algorithm above. * Firstly, check if `G` is a multigraph multigraph \= G.is\_multigraph() * Then, replace indegree\_map\[child\] \-= 1 with indegree\_map\[child\] \-= len(G\[node\]\[child\]) if multigraph else 1 #### Addendum: The graph may have changed during the iteration.[#](#addendum-the-graph-may-have-changed-during-the-iteration "Link to this heading") Between passing different levels in a topological sort, the graph could change. We need to check this while the `while` loop is running. * To do this, just replace for node in this\_generation: for child in G.neighbors(node): indegree\_map\[child\] \-= 1 with for node in this\_generation: if node not in G: raise RuntimeError("Graph changed during iteration") for child in G.neighbors(node): try: indegree\_map\[child\] \-= 1 except KeyError as e: raise RuntimeError("Graph changed during iteration") from e #### Combine all steps.[#](#combine-all-steps "Link to this heading") Combining all of the above gives the current implementation of the `topological_generations()` function in NetworkX. print(inspect.getsource(nx.topological\_generations)) @nx.\_dispatchable def topological\_generations(G): """Stratifies a DAG into generations. A topological generation is node collection in which ancestors of a node in each generation are guaranteed to be in a previous generation, and any descendants of a node are guaranteed to be in a following generation. Nodes are guaranteed to be in the earliest possible generation that they can belong to. Parameters ---------- G : NetworkX digraph A directed acyclic graph (DAG) Yields ------ sets of nodes Yields sets of nodes representing each generation. Raises ------ NetworkXError Generations are defined for directed graphs only. If the graph \`G\` is undirected, a :exc:\`NetworkXError\` is raised. NetworkXUnfeasible If \`G\` is not a directed acyclic graph (DAG) no topological generations exist and a :exc:\`NetworkXUnfeasible\` exception is raised. This can also be raised if \`G\` is changed while the returned iterator is being processed RuntimeError If \`G\` is changed while the returned iterator is being processed. Examples -------- >>> DG = nx.DiGraph(\[(2, 1), (3, 1)\]) >>> \[sorted(generation) for generation in nx.topological\_generations(DG)\] \[\[2, 3\], \[1\]\] Notes ----- The generation in which a node resides can also be determined by taking the max-path-distance from the node to the farthest leaf node. That value can be obtained with this function using \`enumerate(topological\_generations(G))\`. See also -------- topological\_sort """ if not G.is\_directed(): raise nx.NetworkXError("Topological sort not defined on undirected graphs.") multigraph = G.is\_multigraph() indegree\_map = {v: d for v, d in G.in\_degree() if d > 0} zero\_indegree = \[v for v, d in G.in\_degree() if d == 0\] while zero\_indegree: this\_generation = zero\_indegree zero\_indegree = \[\] for node in this\_generation: if node not in G: raise RuntimeError("Graph changed during iteration") for child in G.neighbors(node): try: indegree\_map\[child\] -= len(G\[node\]\[child\]) if multigraph else 1 except KeyError as err: raise RuntimeError("Graph changed during iteration") from err if indegree\_map\[child\] == 0: zero\_indegree.append(child) del indegree\_map\[child\] yield this\_generation if indegree\_map: raise nx.NetworkXUnfeasible( "Graph contains a cycle or graph changed during iteration" ) Let’s finally see what the result will be on the `clothing_graph`. list(nx.topological\_generations(clothing\_graph)) \[\['undershorts', 'shirt', 'socks', 'watch'\],\ \['pants', 'tie'\],\ \['belt', 'shoes'\],\ \['jacket'\]\] References[#](#references "Link to this heading") -------------------------------------------------- Contents --- # NetworkX 3.4.1 — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NetworkX 3.4.1[#](#networkx-3-4-1 "Link to this heading") ========================================================== Release date: 11 October 2024 Supports Python 3.10, 3.11, 3.12, and 3.13. NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. For more information, please visit our [website](https://networkx.org/) and our [gallery of examples](../auto_examples/index.html#examples-gallery) . Please send comments and questions to the [networkx-discuss mailing list](http://groups.google.com/group/networkx-discuss) . Maintenance[#](#maintenance "Link to this heading") ---------------------------------------------------- * Remove old deprecation decorator ([#7669](https://github.com/networkx/networkx/pull/7669) ). * MAINT: delay loading of backend\_info to after imports ([#7672](https://github.com/networkx/networkx/pull/7672) ). Contributors[#](#contributors "Link to this heading") ------------------------------------------------------ 2 authors added to this release (alphabetically): * Dan Schult ([@dschult](https://github.com/dschult) ) * Jarrod Millman ([@jarrodmillman](https://github.com/jarrodmillman) ) 3 reviewers added to this release (alphabetically): * Jarrod Millman ([@jarrodmillman](https://github.com/jarrodmillman) ) * Mridul Seth ([@MridulS](https://github.com/MridulS) ) * Ross Barnowski ([@rossbar](https://github.com/rossbar) ) \_These lists are automatically generated, and may not be complete or may contain duplicates.\_ On this page --- # Release Process — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Release Process[#](#release-process "Link to this heading") ============================================================ * Set release variables: > export VERSION= export PREVIOUS= export ORG=”networkx” export REPO=”networkx” If this is a prerelease: > export NOTES=”doc/release/release\_dev.rst” If this is release: > export NOTES=”doc/release/release\_${VERSION}.rst” git rm doc/release/release\_dev.rst * Autogenerate release notes: > changelist \\({ORG}/\\){REPO} networkx-\\({PREVIOUS} main --version \\){VERSION} –out \\({NOTES} --format rst changelist \\){ORG}/\\({REPO} networkx-\\){PREVIOUS} main –version \\({VERSION} --out \\){VERSION}.md * Edit `doc/_static/version_switcher.json` in order to add the release, move the key value pair `"preferred": true` to the most recent stable version, and commit. * Update `doc/release/index.rst`. * Update `__version__` in `networkx/__init__.py`. * Commit changes: git add networkx/\_\_init\_\_.py ${NOTES} doc/\_static/version\_switcher.json doc/release/index.rst git commit -m "Designate ${VERSION} release" * Add the version number as a tag in git: git tag -s networkx-${VERSION} -m "signed ${VERSION} tag" * Push the new meta-data to github: git push \--tags origin main (where `origin` is the name of the `github.com:networkx/networkx` repository.) * Review the github release page: https://github.com/networkx/networkx/tags * Update documentation on the web: The documentation is kept in a separate repo: networkx/documentation * Wait for the CI service to deploy to GitHub Pages * Sync your branch with the remote repo: `git pull`. * Copy the documentation built by the CI service. Assuming you are at the top-level of the `documentation` repo: \# FIXME - use eol\_banner.html cp -a latest ../networkx-${VERSION} git reset --hard mv ../networkx-${VERSION} . rm -rf stable cp -rf networkx-${VERSION} stable git add networkx-${VERSION} stable git commit -m "Add ${VERSION} docs" git push # force push---be careful! * Update `__version__` in `networkx/__init__.py`. > * Commit and push changes: > > git add networkx/\_\_init\_\_.py > git commit \-m "Bump release version" > git push origin main > * Update the web frontpage: The webpage is kept in a separate repo: networkx/website * Sync your branch with the remote repo: `git pull`. If you try to `make github` when your branch is out of sync, it creates headaches. * Update `build/index.html`. * Edit `build/_static/docversions.js` and commit * Push your changes to the repo. * Deploy using `make github`. * Post release notes on mailing list. * [networkx-discuss@googlegroups.com](mailto:networkx-discuss%40googlegroups.com) --- # Page not found · GitHub Pages 404 === **File not found** The site configured at this address does not contain the requested file. If this is your site, make sure that the filename case matches the URL as well as any file permissions. For root URLs (like `http://example.com/`) you must provide an `index.html` file. [Read the full documentation](https://help.github.com/pages/) for more information about using **GitHub Pages**. [GitHub Status](https://githubstatus.com) — [@githubstatus](https://twitter.com/githubstatus) [![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpFMTZCRDY3REIzRjAxMUUyQUQzREIxQzRENUFFNUM5NiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpFMTZCRDY3RUIzRjAxMUUyQUQzREIxQzRENUFFNUM5NiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkUxNkJENjdCQjNGMDExRTJBRDNEQjFDNEQ1QUU1Qzk2IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkUxNkJENjdDQjNGMDExRTJBRDNEQjFDNEQ1QUU1Qzk2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+SM9MCAAAA+5JREFUeNrEV11Ik1EY3s4+ddOp29Q5b0opCgKFsoKoi5Kg6CIhuwi6zLJLoYLopq4qsKKgi4i6CYIoU/q5iDAKs6syoS76IRWtyJ+p7cdt7sf1PGOD+e0c3dygAx/67ZzzPM95/877GYdHRg3ZjMXFxepQKNS6sLCwJxqNNuFpiMfjVs4ZjUa/pmmjeD6VlJS8NpvNT4QQ7mxwjSsJiEQim/1+/9lgMHgIr5ohuxG1WCw9Vqv1clFR0dCqBODElV6v90ogEDjGdYbVjXhpaendioqK07CIR7ZAqE49PT09BPL2PMgTByQGsYiZlQD4uMXtdr+JxWINhgINYhGT2MsKgMrm2dnZXgRXhaHAg5jEJodUAHxux4LudHJE9RdEdA+i3Juz7bGHe4mhE9FNrgwBCLirMFV9Okh5eflFh8PR5nK5nDabrR2BNJlKO0T35+Li4n4+/J+/JQCxhmu5h3uJoXNHPbmWZAHMshWB8l5/ipqammaAf0zPDDx1ONV3vurdidqwAQL+pEc8sLcAe1CCvQ3YHxIW8Pl85xSWNC1hADDIv0rIE/o4J0k3kww4xSlwIhcq3EFFOm7KN/hUGOQkt0CFa5WpNJlMvxBEz/IVQAxg/ZRZl9wiHA63yDYieM7DnLP5CiAGsC7I5sgtYKJGWe2A8seFqgFJrJjEPY1Cn3pJ8/9W1e5VWsFDTEmFrBcoDhZJEQkXuhICMyKpjhahqN21hRYATKfUOlDmkygrR4o4C0VOLGJKrOITKB4jijzdXygBKixyC5TDQdnk/Pz8qRw6oOWGlsTKGOQW6OH6FBWsyePxdOXLTgxiyebILZCjz+GLgMIKnXNzc49YMlcRdHXcSwxFVgTInQhC9G33UhNoJLuqq6t345p9y3eUy8OTk5PjAHuI9uo4b07FBaOhsu0A4Unc+T1TU1Nj3KsSSE5yJ65jqF2DDd8QqWYmAZrIM2VlZTdnZmb6AbpdV9V6ec9znf5Q7HjYumdRE0JOp3MjitO4SFa+cZz8Umqe3TCbSLvdfkR/kWDdNQl5InuTcysOcpFT35ZrbBxx4p3JAHlZVVW1D/634VRt+FvLBgK/v5LV9WS+10xMTEwtRw7XvqOL+e2Q8V3AYIOIAXQ26/heWVnZCVfcyKHg2CBgTpmPmjYM8l24GyaUHyaIh7XwfR9ErE8qHoDfn2LTNAVC0HX6MFcBIP8Bi+6F6cdW/DICkANRfx99fEYFQ7Nph5i/uQiA214gno7K+guhaiKg9gC62+M8eR7XsBsYJ4ilam60Fb7r7uAj8wFyuwM1oIOWgfmDy6RXEEQzJMPe23DXrVS7rtyD3Df8z/FPgAEAzWU5Ku59ZAUAAAAASUVORK5CYII=)](/) [![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpEQUM1QkUxRUI0MUMxMUUyQUQzREIxQzRENUFFNUM5NiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpEQUM1QkUxRkI0MUMxMUUyQUQzREIxQzRENUFFNUM5NiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkUxNkJENjdGQjNGMDExRTJBRDNEQjFDNEQ1QUU1Qzk2IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkUxNkJENjgwQjNGMDExRTJBRDNEQjFDNEQ1QUU1Qzk2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+hfPRaQAAB6lJREFUeNrsW2mME2UYbodtt+2222u35QheoCCYGBQligIJgkZJNPzgigoaTEj8AdFEMfADfyABkgWiiWcieK4S+QOiHAYUj2hMNKgYlEujpNttu9vttbvdw+chU1K6M535pt3ubHCSyezR+b73eb73+t7vrfXsufOW4bz6+vom9/b23ovnNNw34b5xYGAgODg46Mbt4mesVmsWd1qSpHhdXd2fuP/Afcput5/A88xwymcdBgLqenp6FuRyuWV4zu/v759QyWBjxoz5t76+/gun09mK5xFyakoCAPSaTCazNpvNPoYVbh6O1YKGRF0u13sNDQ27QMzfpiAAKj0lnU6/gBVfAZW2WWpwwVzy0IgP3G73FpjI6REhAGA9qVRqA1b9mVoBVyIC2tDi8Xg24+dUzQiAbS/s7Ox8G2o/3mKCC+Zw0efzPQEfcVjYrARX3dbV1bUtHo8fMgt42f+Mp0yUTVQbdWsAHVsikdiHkHaPxcQXQufXgUBgMRxme9U0AAxfH4vFvjM7eF6UkbJS5qoQwEQGA57Ac5JllFyUVZZ5ckUEgMVxsK2jlSYzI+QXJsiyjzNEAJyJAzb/KQa41jJKL8pODMQiTEAymXw5n8/P0IjD3bh7Rgog59aanxiIRTVvV/oj0tnHca/WMrVwODwB3raTGxzkBg/gnZVapFV62Wy2n5AO70HM/5wbJ0QnXyQSaVPDIuNZzY0V3ntHMwxiwHA0Gj2Np7ecIBDgaDAYXKCQJM1DhrgJ3nhulcPbl8j4NmHe46X/g60fwbz3aewjkqFQaAqebWU1AOqyQwt8Id6qEHMc97zu7u7FGGsn7HAiVuosVw7P35C1nccdgSCxop1dHeZswmfHMnxBo6ZTk+jN8dl/vF7vWofDsa+MLN9oEUBMxOb3+1eoEsBVw6Zmua49r8YmhAKDiEPcMwBsxMiqQ+ixzPFxZyqRpXARG/YOr1ObFJ0gUskXBbamcR1OKmMUvDxHRAu8/LmY3jFLMUpFqz9HxG65smYJdyKyECOxDiEAe/p1gjF2oonivZAsxVgl2daa4EQWCW6J55qFAFFZiJWYLxNQy2qOSUzGRsyXCUDIeliwAHEO4WSlWQBRFoZakXcKmCXmyXAKs0Ve9vl8q42WoIYpJU4hV3hKcNs8m9gl7p/xQ73eF5kB4j5mNrWmTJRNwAzqiV1CxjVTZCIkEq+Z1bZFZSN2CenmVAFVy4Plz8xKAGWjjAKFk6lCBMDR/MJjLLMSQNm43xAiQKTaA+9/wewhDjL+JVI1kkTSSOTcKbMTwPqESAot6dn6Fr1gHwVJju6IRuyiByPuUUBAg5DGkAgBmxlvdgIEK9gDkohdY/BJo4CAG0R8miRSsGABkgVQs4KXu098IgUXSSRsFAoKZiVAVDY2WUiiPTjYRi41KwGisrGsLtlsth8Fiwnz2fBkQvWfRtlE3iF2yW63/yCacXZ1dW02GwGyTFaRd4idJnCKHRaCxYRHoG5LTKT6SyiToP1fJHbmAYPYRR0UnZQtMnA6s0zg+GZBlt0Gdo7EPHgpE3Q6nZ8YyLhc8Xj8MJh/aKTAY+5FPAKHLE7RdwuYJZmNwzyCMkBCYyKROJBMJl9B/PXXCjjmCmDOVzH3fiPpObEWGqoKe4EBl8v1hlqsdLvd23mkxHM9pc9kMpmno9HoeTii7ewbHEZPPx1ztLS1tV3AnGuMjiNjvbQFuHw6zDo5By7dTPAQNBgMLrRarTkSls1mnwT7uwp9virx9QzbW/HuV/j5d/b+6jniKlllP8lkeONJDk+dq9GsQTnC4fB1heO0K47Hwe7WdDr9nAKgXwOBwHI+C45Htj1d6sd429TUNEcmUdc+PRaLHcvn87dXW4ugzdsaGxufL94NFv9zi1J7GVbhlvb2dnaJ3SVrxfc+n2+NTsZ7/H7/Mr3g5XdSIHyJSH1PZ+7fToyl2+ErqilgZ4NaLYB9goVGaHjR93Hv1ZrU4XDsFT20kH3PObzbWk0CgG1jacVIUnAQb9F+VexyLMzkpcLv0IJV7AHQIOCAUYHx7v5qgScmYHtTqSAyZLEJTK22Bie4iq3xsqpm4SAf9Hq9a2DnJ4uLK3SEULcdRvp3i3zHySqpficxEdsQc1NrlYXXvR+O7qASSezXB+h1SuUomgg9LL8BUoV4749EIolKh+EiqWmqVEZlDgHks2pxHw7xTqUQw9J5NcAXOK10AGIoZ6Zli6JY6Z1Q461KoZ4NiKLHarW+KDsxlDUPHZ5zPQZqUVDPJsTqb5n9malbpAh8C2XXDLl62+WZIDFRUlNVOiwencnNU3aQEkL+cDMSoLvZo2fQB7AJssNAuFuvorlDVVkkg2I87+jo2K2QAVphDrfyViK5VqtO34OkaxXCp+7drdDBCAdubm6eidX+2WwqT5komwh4YQLk+H4aE93h8Xg2gvHekQZOGSgLZTLyDTLJ4Lx9/KZWKBSainT4Iy3FqQBfnUZR42PKQFksBr9QKVXCPusD3OiA/RkQ5kP8qV/Jl1WywAp/6+dcmPM2zL1UrUahe4JqfnWWKXIul3uUbfP8njAFLW1OFr3gdFtZ72cNH+PtQT7/brW+NXqJAHh0y9V8/U/A1U7AfwIMAD7mS3pCbuWJAAAAAElFTkSuQmCC)](/) --- # Lowest Common Ancestor — NetworkX Notebooks [Skip to main content](#main-content) Back to top Ctrl+K [![NetworkX Notebooks - Home](../../../_static/networkx_banner.svg) ![NetworkX Notebooks - Home](../../../_static/networkx_banner.svg)](../../../index.html) * [GitHub](https://github.com/networkx/nx-guides/ "GitHub") Search Ctrl+K * [![Binder logo](../../../_static/images/logo_binder.svg)Binder](https://mybinder.org/v2/gh/networkx/nx-guides/main?urlpath=tree/site/content/algorithms/lca/LCA.md "Launch on Binder") * [Repository](https://github.com/networkx/nx-guides "Source repository") * [Suggest edit](https://github.com/networkx/nx-guides/edit/main/site/content/algorithms/lca/LCA.md "Suggest edit") * [Open issue](https://github.com/networkx/nx-guides/issues/new?title=Issue%20on%20page%20%2Fcontent/algorithms/lca/LCA.html&body=Your%20issue%20content%20here. "Open an issue") * [.ipynb](../../../_sources/content/algorithms/lca/LCA.ipynb "Download notebook file") * [.md](../../../_sources/content/algorithms/lca/LCA.md "Download source file") * .pdf Lowest Common Ancestor ====================== Contents -------- Lowest Common Ancestor[#](#lowest-common-ancestor "Link to this heading") ========================================================================== In this tutorial, we will explore the python implementation of the lowest common ancestor algorithm [\[1\]](#id2) in NetworkX at [`networkx/algorithms/lowest_common_ancestor.py`](https://github.com/networkx/networkx/blob/main/networkx/algorithms/lowest_common_ancestors.py) . This notebook expects readers to be familiar with the NetworkX API. If you are new to NetworkX, you can go through the [introductory tutorial](https://networkx.org/documentation/latest/tutorial.html) . Import packages[#](#import-packages "Link to this heading") ------------------------------------------------------------ import matplotlib.pyplot as plt import networkx as nx from networkx.drawing.nx\_agraph import graphviz\_layout from itertools import chain, count, combinations\_with\_replacement Definitions[#](#definitions "Link to this heading") ---------------------------------------------------- Before diving into the algorithm, let’s first remember the concepts of an ancestor node and a descendant node. * **Ancestor:** Given a rooted tree, any node \\(u\\) which is on the path from root node to \\(v\\) is an ancestor of \\(u\\). * **Descendant:** A descendant of a node is either a child of the node or a child of some descendant of the node. * **Lowest Common Ancestor:** For two of nodes \\(u\\) and \\(v\\) in a tree, the lowest common ancestor is the lowest (i.e. deepest) node which is an ancestor of both \\(u\\) and \\(v\\). Example[#](#example "Link to this heading") -------------------------------------------- It is always a good idea to learn concepts with an example. Consider the following evolutionary tree. We will draw a directed version of it and define the ancestor/descendant relationships. ![image:evolutionary tree](../../../_images/evol_tree.png) Let’s first draw the tree using NetworkX. T \= nx.DiGraph() T.add\_edges\_from( \[\ ("Vertebrate", "Lamprey"),\ ("Vertebrate", "Jawed V."),\ ("Jawed V.", "Sunfish"),\ ("Jawed V.", "Tetrapod"),\ ("Tetrapod", "Newt"),\ ("Tetrapod", "Amniote"),\ ("Amniote", "Lizard"),\ ("Amniote", "Mammal"),\ ("Mammal", "Bear"),\ ("Mammal", "Chimpanzee"),\ \] ) pos \= graphviz\_layout(T, prog\="dot") plt.figure(3, figsize\=(16, 6)) nx.draw( T, pos, with\_labels\=True, node\_size\=4000, node\_color\="brown", font\_size\=11, font\_color\="White", ) plt.show() ![../../../_images/51ae7a0377a529af7ad656f023513a19122e947da8cafb98ae5ee176afd9ce09.png](../../../_images/51ae7a0377a529af7ad656f023513a19122e947da8cafb98ae5ee176afd9ce09.png) Consider the tree above and observe the following relationships: * Ancestors of node Mammal: * For this, we will follow the path from root to node Mammal. * Nodes Vertebrate, Jawed Vertebrate, Tetrapod and Amniote -which are on this path- are ancestors of Mammal. * Descendants of node Mammal: * Bear and Chimpanzee are the child of Mammal. Thus, they are its descendants. * Lowest Common Ancestor of Mammal and Newt: * Ancestors of Mammal are Vertebrate, Jawed Vertebrate, Tetrapod and Amniote. * Ancestors of Newt are Vertebrate, Jawed Vertebrate, and Tetrapod. * Among the common ancestors, the lowest (i.e. farthest away from the root) one is Tetrapod. _Note that, in terms of lowest common ancestor algorithms, every node is considered as an ancestor itself._ NetworkX’s Implementation of Lowest Common Ancestor Algorithm[#](#networkx-s-implementation-of-lowest-common-ancestor-algorithm "Link to this heading") -------------------------------------------------------------------------------------------------------------------------------------------------------- NetworkX uses a naive algorithm to find the lowest common ancestor of given pairs of nodes. In this section, we will introduce it step by step. ### Step 1: Check if the type of input graph is DAG.[#](#step-1-check-if-the-type-of-input-graph-is-dag "Link to this heading") Lowest common ancestor algorithms under NetworkX are implemented only for directed acyclic graphs with at least one node. For this, the source code first checks if the input graph is a valid one or not. def naive\_all\_pairs\_lowest\_common\_ancestor(G, pairs\=None): if not nx.is\_directed\_acyclic\_graph(G): raise nx.NetworkXError("LCA only defined on directed acyclic graphs.") elif len(G) \== 0: raise nx.NetworkXPointlessConcept("LCA meaningless on null graphs.") If the “pairs” argument is not set, we consider all unordered pairs of nodes in G by default, e.g. we do not get both (b, a) and (a, b) but only one of them. If pairs are already specified, we check if every node in pairs exists in the input graph. if pairs is None: from itertools import combinations\_with\_replacement pairs \= combinations\_with\_replacement(G, 2) else: pairs \= dict.fromkeys(pairs) nodeset \= set(G) for pair in pairs: if set(pair) \- nodeset: raise nx.NodeNotFound( f"Node(s) {set(pair) \- nodeset} from pair {pair} not in G." ) ### Step 2: Find ancestors of all nodes in G.[#](#step-2-find-ancestors-of-all-nodes-in-g "Link to this heading") Once the input validation is done, we find all ancestors of every node in the pairs and store these information in a cache. ancestor\_cache \= {} for v, w in pairs: if v not in ancestor\_cache: ancestor\_cache\[v\] \= nx.ancestors(G, v) ancestor\_cache\[v\].add(v) if w not in ancestor\_cache: ancestor\_cache\[w\] \= nx.ancestors(G, w) ancestor\_cache\[w\].add(w) ### Step 3: Find common ancestors[#](#step-3-find-common-ancestors "Link to this heading") For each pair (v, w), we determine nodes that appear in both ancestor lists of \\(v\\) and \\(w\\). (i.e. find all common ancestors) common\_ancestors \= ancestor\_cache\[v\] & ancestor\_cache\[w\] ### Step 4: Find a node in common ancestors which is located at the lowest level in the graph.[#](#step-4-find-a-node-in-common-ancestors-which-is-located-at-the-lowest-level-in-the-graph "Link to this heading") We start with an arbitrary node \\(v\\) from the set of common ancestors. We follow the arbitrary outgoing edges remaining in the set of common ancestors, until reaching a node with no outgoing edge to another of the common ancestors. v \= next(iter(common\_ancestors)) while True: successor \= None for w in G.successors(v): if w in common\_ancestors: successor \= w break if successor is None: return v v \= successor We can see the result of our algorithm for a simple directed acyclic graph. Assume that our graph G is as follows and we wish to find lowest common ancestors for all pairs. For this, we need to call the `all_pairs_lowest_common_ancestor` method. \# Generating and visualizing our DAG G \= nx.DiGraph() G.add\_edges\_from(\[(1, 0), (2, 0), (3, 2), (3, 1), (4, 2), (4, 3)\]) pairs \= combinations\_with\_replacement(G, 2) pos \= graphviz\_layout(G, prog\="dot") plt.figure(3, figsize\=(5, 3)) nx.draw( G, pos, with\_labels\=True, node\_size\=1500, node\_color\="darkgreen", font\_size\=14, font\_color\="White", ) plt.show() ![../../../_images/d66c3e2c8575eb24c98a3b058bcbdf1178e9ea940b5e96e0e40c40e2547d8ad8.png](../../../_images/d66c3e2c8575eb24c98a3b058bcbdf1178e9ea940b5e96e0e40c40e2547d8ad8.png) dict(nx.all\_pairs\_lowest\_common\_ancestor(G)) {(1, 1): 1, (1, 0): 1, (1, 2): 3, (1, 3): 3, (1, 4): 4, (0, 0): 0, (0, 2): 2, (0, 3): 3, (0, 4): 4, (2, 2): 2, (2, 3): 3, (2, 4): 4, (3, 3): 3, (3, 4): 4, (4, 4): 4} Time & Space Complexity[#](#time-space-complexity "Link to this heading") -------------------------------------------------------------------------- Naive implementation of lowest common ancestor algorithm finds all ancestors of all nodes in the given pairs. Let the number of nodes given in the pairs be P. In the worst case, finding ancestors of a single node will take O(|V|) times where |V| is the number of nodes. Thus, constructing the ancestor cache of a graph will take O(|V|\*P) times. This step will dominate the others and determine the worst-case running time of the algorithm. The space complexity of the algorithm will also be determined by the ancestor cache. For each node in the given pairs, there might be O(|V|) ancestors. Thus, space complexity is also O(|V|\*P). References[#](#references "Link to this heading") -------------------------------------------------- Contents --- # NetworkX 3.4 — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NetworkX 3.4[#](#networkx-3-4 "Link to this heading") ====================================================== Release date: 10 October 2024 Supports Python 3.10, 3.11, 3.12, and 3.13. NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. For more information, please visit our [website](https://networkx.org/) and our [gallery of examples](../auto_examples/index.html#examples-gallery) . Please send comments and questions to the [networkx-discuss mailing list](http://groups.google.com/group/networkx-discuss) . API Changes[#](#api-changes "Link to this heading") ---------------------------------------------------- * Expires the `forest_str` deprecation ([#7414](https://github.com/networkx/networkx/pull/7414) ). * \[ENH, BUG\]: added `colliders` and `v_structures` and deprecated `compute_v_structures` in `dag.py` ([#7398](https://github.com/networkx/networkx/pull/7398) ). * Expires the `random_tree` deprecation ([#7415](https://github.com/networkx/networkx/pull/7415) ). * Expire deprecation for strongly\_connected\_components\_recursive ([#7420](https://github.com/networkx/networkx/pull/7420) ). * Expire deprecated `sort_neighbors` param in `generic_bfs_edges` ([#7417](https://github.com/networkx/networkx/pull/7417) ). * Rm deprecated normalized param from s\_metric ([#7418](https://github.com/networkx/networkx/pull/7418) ). * Expire deprecated nx.join in favor of join\_trees ([#7419](https://github.com/networkx/networkx/pull/7419) ). * Remove depercated Edmonds class for 3.4 ([#7447](https://github.com/networkx/networkx/pull/7447) ). * Remove deprecated MultiDiGraph\_EdgeKey for 3.4 ([#7448](https://github.com/networkx/networkx/pull/7448) ). * Add `edges` keyword/deprecate `link` keyword arguments in `JSON` input-output ([#7565](https://github.com/networkx/networkx/pull/7565) ). * Revert breaking change to `node_link_*` link defaults ([#7652](https://github.com/networkx/networkx/pull/7652) ). Enhancements[#](#enhancements "Link to this heading") ------------------------------------------------------ * Add a `nodelist` feature to `from_numpy_array` ([#7412](https://github.com/networkx/networkx/pull/7412) ). * Prioritize edgelist representations in `to_networkx_graph` ([#7424](https://github.com/networkx/networkx/pull/7424) ). * Adds initial debug logging calls to \_dispatchable ([#7300](https://github.com/networkx/networkx/pull/7300) ). * add: nodes attribute is modifiable ([#7532](https://github.com/networkx/networkx/pull/7532) ). * Enable config to be used as context manager ([#7363](https://github.com/networkx/networkx/pull/7363) ). * Added code to handle multi-graph in mst ([#7454](https://github.com/networkx/networkx/pull/7454) ). * Enable caching by default ([#7498](https://github.com/networkx/networkx/pull/7498) ). * #7546 More detail error message for pydot ([#7558](https://github.com/networkx/networkx/pull/7558) ). * Fix weakly\_connected\_components() performance on graph view ([#7586](https://github.com/networkx/networkx/pull/7586) ). * Forceatlas2 ([#7543](https://github.com/networkx/networkx/pull/7543) ). * avoid iteration and use boolean indexing ([#7591](https://github.com/networkx/networkx/pull/7591) ). * Hide edges with a weight of None in simple\_paths ([#7583](https://github.com/networkx/networkx/pull/7583) ). * Improved running time for harmonic centrality ([#7595](https://github.com/networkx/networkx/pull/7595) ). * Add remove attribute functions ([#7569](https://github.com/networkx/networkx/pull/7569) ). * Log “can/should run” and caching in dispatch machinery ([#7568](https://github.com/networkx/networkx/pull/7568) ). * Individualize drawing attributes ([#7570](https://github.com/networkx/networkx/pull/7570) ). * added nx-parallel gsoc project ([#7620](https://github.com/networkx/networkx/pull/7620) ). * Harmonic diameter ([#5251](https://github.com/networkx/networkx/pull/5251) ). * Allow dispatch machinery to fall back to networkx ([#7585](https://github.com/networkx/networkx/pull/7585) ). * Add `create_using` parameter for random graphs ([#5672](https://github.com/networkx/networkx/pull/5672) ). * Add config option to disable warning when using cached value ([#7497](https://github.com/networkx/networkx/pull/7497) ). Bug Fixes[#](#bug-fixes "Link to this heading") ------------------------------------------------ * Fix graph name attribute for `complete_bipartite_graph` ([#7399](https://github.com/networkx/networkx/pull/7399) ). * Remove import warnings during to\_networkx\_graph conversion ([#7426](https://github.com/networkx/networkx/pull/7426) ). * Fix nx.from\_pandas\_edgelist so edge keys are not added as edge attributes and edge keys ([#7445](https://github.com/networkx/networkx/pull/7445) ). * Fix `from_pandas_edgelist` for MultiGraph given edge\_key ([#7466](https://github.com/networkx/networkx/pull/7466) ). * Fix dispatch tests when using numpy 2 ([#7506](https://github.com/networkx/networkx/pull/7506) ). * \[ENH, BUG\]: added `colliders` and `v_structures` and deprecated `compute_v_structures` in `dag.py` ([#7398](https://github.com/networkx/networkx/pull/7398) ). * Fix reading edgelist when delimiter is whitespace, e.g. tab ([#7465](https://github.com/networkx/networkx/pull/7465) ). * Ensure we always raise for unknown backend in `backend=` ([#7494](https://github.com/networkx/networkx/pull/7494) ). * Prevent `to_agraph` from modifying graph argument ([#7610](https://github.com/networkx/networkx/pull/7610) ). * Implementing iterative removal of non\_terminal\_leaves in Steiner Tree approximation ([#7422](https://github.com/networkx/networkx/pull/7422) ). * Only allow connected graphs in `eigenvector_centrality_numpy` ([#7549](https://github.com/networkx/networkx/pull/7549) ). * CI: Fix typo in nightly run pip install ([#7625](https://github.com/networkx/networkx/pull/7625) ). Documentation[#](#documentation "Link to this heading") -------------------------------------------------------- * Document missing shortest\_path functions ([#7394](https://github.com/networkx/networkx/pull/7394) ). * Optimal Edit Paths Return Section Improved ([#7375](https://github.com/networkx/networkx/pull/7375) ). * Minor updates to simple\_cycles docstring ([#7421](https://github.com/networkx/networkx/pull/7421) ). * DOC: Clarifying `NetworkXPointlessConcept` exception ([#7434](https://github.com/networkx/networkx/pull/7434) ). * DOC: updated `pairs.py` ([#7416](https://github.com/networkx/networkx/pull/7416) ). * Add docstring example for directed tree ([#7449](https://github.com/networkx/networkx/pull/7449) ). * Change docs of `shortest_path_length` so return is number instead of int ([#7477](https://github.com/networkx/networkx/pull/7477) ). * Use intersphinx\_registry to manage intersphinx mapping ([#7481](https://github.com/networkx/networkx/pull/7481) ). * Ma: fix some spelling errors in docs ([#7480](https://github.com/networkx/networkx/pull/7480) ). * Update NetworkX reference links in doc index ([#7500](https://github.com/networkx/networkx/pull/7500) ). * strong product docs update ([#7511](https://github.com/networkx/networkx/pull/7511) ). * Refactoring and enhancing user-facing `Backend and Configs` docs ([#7404](https://github.com/networkx/networkx/pull/7404) ). * Fixed the citation in `dominance.py` \[Issue #7522\] ([#7524](https://github.com/networkx/networkx/pull/7524) ). * Clarify generation number in `dorogovtsev_goltsev_mendes_graph()` ([#7473](https://github.com/networkx/networkx/pull/7473) ). * Add `Introspection` section to backends docs ([#7556](https://github.com/networkx/networkx/pull/7556) ). * DOC: Added `default_config` in `get_info`’s description ([#7567](https://github.com/networkx/networkx/pull/7567) ). * Prettify `README.rst` ([#7514](https://github.com/networkx/networkx/pull/7514) ). * DOC: Fix typo in the code snippet provided in the docstring of nx\_pydot.pydot\_layout() ([#7572](https://github.com/networkx/networkx/pull/7572) ). * Fix installation instructions for `default` extras in README ([#7574](https://github.com/networkx/networkx/pull/7574) ). * Add missing metadata to v3.3 release notes ([#7592](https://github.com/networkx/networkx/pull/7592) ). * Correct the members of steering council ([#7604](https://github.com/networkx/networkx/pull/7604) ). * Fix dispatch docs formatting ([#7619](https://github.com/networkx/networkx/pull/7619) ). * Add to Contributor List ([#7621](https://github.com/networkx/networkx/pull/7621) ). * Example fix for issue 7633 ([#7634](https://github.com/networkx/networkx/pull/7634) ). * Fix: Correct community color assignment in Girvan-Newman community detection ([#7644](https://github.com/networkx/networkx/pull/7644) ). * Updated docstring for generators/karate\_club\_graph() ([#7626](https://github.com/networkx/networkx/pull/7626) ). * Updates documentation to include details about using NetworkX with backends ([#7611](https://github.com/networkx/networkx/pull/7611) ). * Add examples section to `to_scipy_sparse_array` ([#7627](https://github.com/networkx/networkx/pull/7627) ). * Add examples to docstrings of subgraph\_(iso/monomorphism) methods ([#7622](https://github.com/networkx/networkx/pull/7622) ). Maintenance[#](#maintenance "Link to this heading") ---------------------------------------------------- * Simplify flow func augmentation logic in `connectivity` module ([#7367](https://github.com/networkx/networkx/pull/7367) ). * A few more doctest skips for mpl/np dependencies ([#7403](https://github.com/networkx/networkx/pull/7403) ). * Remove repetitive words ([#7406](https://github.com/networkx/networkx/pull/7406) ). * FilterAdjacency: \_\_len\_\_ is recalculated unnecessarily #7377 ([#7378](https://github.com/networkx/networkx/pull/7378) ). * Add check for empty graphs in `flow_hierarchy` ([#7393](https://github.com/networkx/networkx/pull/7393) ). * Use nodelist feature of from\_numpy\_array ([#7425](https://github.com/networkx/networkx/pull/7425) ). * Cleanup remaining usages of deprecated `random_tree` in package ([#7411](https://github.com/networkx/networkx/pull/7411) ). * Add check for empty graphs in `non_randomness` ([#7395](https://github.com/networkx/networkx/pull/7395) ). * Update tests for macOS Sonoma v14 ([#7437](https://github.com/networkx/networkx/pull/7437) ). * Update doc requirements ([#7435](https://github.com/networkx/networkx/pull/7435) ). * Update pygraphviz ([#7441](https://github.com/networkx/networkx/pull/7441) ). * Always cache graph attrs for better cache behavior ([#7455](https://github.com/networkx/networkx/pull/7455) ). * retain adjacency order in nx-loopback copy of networkx graph ([#7432](https://github.com/networkx/networkx/pull/7432) ). * DEV: Add files generated by benchmarking to .gitignore ([#7461](https://github.com/networkx/networkx/pull/7461) ). * Remove redundant graph copy in `algorithms.bridges.bridges()` ([#7471](https://github.com/networkx/networkx/pull/7471) ). * CI: Add GitHub artifact attestations to package distribution ([#7459](https://github.com/networkx/networkx/pull/7459) ). * Add `polynomials.py` to `needs_numpy` ([#7493](https://github.com/networkx/networkx/pull/7493) ). * MAINT: Rename `LoopbackDispatcher` to `LoopbackBackendInterface` and `dispatcher` to `backend_interface` ([#7492](https://github.com/networkx/networkx/pull/7492) ). * CI: update action that got moved org ([#7503](https://github.com/networkx/networkx/pull/7503) ). * Update momepy ([#7507](https://github.com/networkx/networkx/pull/7507) ). * Fix pygraphviz install on Windows ([#7512](https://github.com/networkx/networkx/pull/7512) ). * MAINT: Made `plot_image_segmentation_spectral_graph_partition` example compatible with scipy 1.14.0 ([#7518](https://github.com/networkx/networkx/pull/7518) ). * Fix CI installation of nx-cugraph in docs workflow ([#7538](https://github.com/networkx/networkx/pull/7538) ). * Minor doc/test tweaks for dorogovtsev\_goltsev\_mendes ([#7535](https://github.com/networkx/networkx/pull/7535) ). * CI: Add timeout limit to coverage job ([#7542](https://github.com/networkx/networkx/pull/7542) ). * Update images used in docs build workflow ([#7537](https://github.com/networkx/networkx/pull/7537) ). * Remove parallelization related TODO comments ([#7226](https://github.com/networkx/networkx/pull/7226) ). * FIX: scipy 1d indexing tripped up numpy? ([#7541](https://github.com/networkx/networkx/pull/7541) ). * Minor touchups to node\_link functions ([#7540](https://github.com/networkx/networkx/pull/7540) ). * Minor updates to colliders v\_structures tests ([#7539](https://github.com/networkx/networkx/pull/7539) ). * Update sphinx gallery config to enable sphinx build caching ([#7548](https://github.com/networkx/networkx/pull/7548) ). * Update geospatial gallery dependencies ([#7508](https://github.com/networkx/networkx/pull/7508) ). * Update ruff pre-commit and config ([#7547](https://github.com/networkx/networkx/pull/7547) ). * More accurate NodeNotFound error message ([#7545](https://github.com/networkx/networkx/pull/7545) ). * Update ruff config ([#7552](https://github.com/networkx/networkx/pull/7552) ). * Add changelist config ([#7551](https://github.com/networkx/networkx/pull/7551) ). * Fix installing nx-cugraph in deploy docs CI ([#7561](https://github.com/networkx/networkx/pull/7561) ). * Fix `nx_pydot.graphviz_layout` for nodes with quoted/escaped chars ([#7588](https://github.com/networkx/networkx/pull/7588) ). * DOC: Rm redundant module from autosummary ([#7599](https://github.com/networkx/networkx/pull/7599) ). * Update numpydoc (1.8) ([#7573](https://github.com/networkx/networkx/pull/7573) ). * Bump minimum pydot version to 3.0 ([#7596](https://github.com/networkx/networkx/pull/7596) ). * CI: Include Python 3.13 in nightly wheel tests ([#7594](https://github.com/networkx/networkx/pull/7594) ). * pydot - Remove Colon Check on Strings ([#7606](https://github.com/networkx/networkx/pull/7606) ). * MAINT: Do not use requirements files in circle CI ([#7553](https://github.com/networkx/networkx/pull/7553) ). * Do not use requirements file in github workflow ([#7495](https://github.com/networkx/networkx/pull/7495) ). * `weisfeiler_lehman_graph_hash`: add `not_implemented_for("multigraph")` decorator ([#7614](https://github.com/networkx/networkx/pull/7614) ). * Update teams doc by running `tools/team_list.py` ([#7616](https://github.com/networkx/networkx/pull/7616) ). * Add single node with self loop check to local and global reaching centrality ([#7350](https://github.com/networkx/networkx/pull/7350) ). * Full test coverage for maxflow in issue #6029 ([#6355](https://github.com/networkx/networkx/pull/6355) ). * CI: Fix typo in nightly run pip install ([#7625](https://github.com/networkx/networkx/pull/7625) ). * DOC: Bring back plausible for docs ([#7639](https://github.com/networkx/networkx/pull/7639) ). * Update minimum dependencies (SPEC 0) ([#7631](https://github.com/networkx/networkx/pull/7631) ). * Update pygraphviz (1.14) ([#7654](https://github.com/networkx/networkx/pull/7654) ). * modified product.py to raise NodeNotFound when ‘root is not in H’ ([#7635](https://github.com/networkx/networkx/pull/7635) ). * Support Python 3.13 ([#7661](https://github.com/networkx/networkx/pull/7661) ). * Use official Python 3.13 release ([#7667](https://github.com/networkx/networkx/pull/7667) ). Other[#](#other "Link to this heading") ---------------------------------------- * chore: fix some typos in comments ([#7427](https://github.com/networkx/networkx/pull/7427) ). Contributors[#](#contributors "Link to this heading") ------------------------------------------------------ 53 authors added to this release (alphabetically): * [@finaltrip](https://github.com/finaltrip) * [@goodactive](https://github.com/goodactive) * [@inbalh1](https://github.com/inbalh1) * [@johnthagen](https://github.com/johnthagen) * [@jrdnh](https://github.com/jrdnh) * [@lejansenGitHub](https://github.com/lejansenGitHub) * Aditi Juneja ([@Schefflera-Arboricola](https://github.com/Schefflera-Arboricola) ) * Alexander Bakhtin ([@bakhtos](https://github.com/bakhtos) ) * Ashwin Nayak ([@ashwin-nayak](https://github.com/ashwin-nayak) ) * Brigitta Sipőcz ([@bsipocz](https://github.com/bsipocz) ) * Casper van Elteren ([@cvanelteren](https://github.com/cvanelteren) ) * Charitha Buddhika Heendeniya ([@buddih09](https://github.com/buddih09) ) * chrizzftd ([@chrizzFTD](https://github.com/chrizzFTD) ) * Cora Schneck ([@cyschneck](https://github.com/cyschneck) ) * Dan Schult ([@dschult](https://github.com/dschult) ) * Erik Welch ([@eriknw](https://github.com/eriknw) ) * Ewout ter Hoeven ([@EwoutH](https://github.com/EwoutH) ) * Fabian Spaeh ([@285714](https://github.com/285714) ) * Gilles Peiffer ([@Peiffap](https://github.com/Peiffap) ) * Gregory Shklover ([@gregory-shklover](https://github.com/gregory-shklover) ) * Jarrod Millman ([@jarrodmillman](https://github.com/jarrodmillman) ) * Jim Hull ([@jmhull](https://github.com/jmhull) ) * Joye Mang ([@joyemang33](https://github.com/joyemang33) ) * Kelvin Chung ([@KelvinChung2000](https://github.com/KelvinChung2000) ) * Koushik\_Nekkanti ([@KoushikNekkanti](https://github.com/KoushikNekkanti) ) * M Bussonnier ([@Carreau](https://github.com/Carreau) ) * Marc-Alexandre Côté ([@MarcCote](https://github.com/MarcCote) ) * Matt Schwennesen ([@mjschwenne](https://github.com/mjschwenne) ) * Matthew Feickert ([@matthewfeickert](https://github.com/matthewfeickert) ) * Maverick18 ([@Aditya-Shandilya1182](https://github.com/Aditya-Shandilya1182) ) * Michael Bolger ([@mbbolger](https://github.com/mbbolger) ) * Miguel Cárdenas ([@miguelcsx](https://github.com/miguelcsx) ) * Mohamed Rezk ([@mohamedrezk122](https://github.com/mohamedrezk122) ) * Mridul Seth ([@MridulS](https://github.com/MridulS) ) * Mudassir Chapra ([@muddi900](https://github.com/muddi900) ) * Orion Sehn ([@OrionSehn](https://github.com/OrionSehn) ) * Orion Sehn ([@OrionSehn-personal](https://github.com/OrionSehn-personal) ) * Peter Cock ([@peterjc](https://github.com/peterjc) ) * Philipp van Kempen ([@PhilippvK](https://github.com/PhilippvK) ) * prathamesh shinde ([@prathamesh901](https://github.com/prathamesh901) ) * Raj Pawar ([@Raj3110](https://github.com/Raj3110) ) * Rick Ratzel ([@rlratzel](https://github.com/rlratzel) ) * Rike-Benjamin Schuppner ([@Debilski](https://github.com/Debilski) ) * Ross Barnowski ([@rossbar](https://github.com/rossbar) ) * Sanchit Ram Arvind ([@sanchitram1](https://github.com/sanchitram1) ) * Sebastiano Vigna ([@vigna](https://github.com/vigna) ) * STEVEN ADAMS ([@hugehope](https://github.com/hugehope) ) * Thomas J. Fan ([@thomasjpfan](https://github.com/thomasjpfan) ) * Till Hoffmann ([@tillahoffmann](https://github.com/tillahoffmann) ) * Vanshika Mishra ([@vanshika230](https://github.com/vanshika230) ) * Woojin Jung ([@WoojinJung-04](https://github.com/WoojinJung-04) ) * Yury Fedotov ([@yury-fedotov](https://github.com/yury-fedotov) ) * Łukasz ([@lkk7](https://github.com/lkk7) ) 28 reviewers added to this release (alphabetically): * [@finaltrip](https://github.com/finaltrip) * [@inbalh1](https://github.com/inbalh1) * [@jrdnh](https://github.com/jrdnh) * Aditi Juneja ([@Schefflera-Arboricola](https://github.com/Schefflera-Arboricola) ) * Bhuvneshwar Chouksey ([@gbhuvneshwar](https://github.com/gbhuvneshwar) ) * Casper van Elteren ([@cvanelteren](https://github.com/cvanelteren) ) * chrizzftd ([@chrizzFTD](https://github.com/chrizzFTD) ) * Dan Schult ([@dschult](https://github.com/dschult) ) * Erik Welch ([@eriknw](https://github.com/eriknw) ) * Fabian Spaeh ([@285714](https://github.com/285714) ) * Gilles Peiffer ([@Peiffap](https://github.com/Peiffap) ) * Jarrod Millman ([@jarrodmillman](https://github.com/jarrodmillman) ) * M Bussonnier ([@Carreau](https://github.com/Carreau) ) * Matt Schwennesen ([@mjschwenne](https://github.com/mjschwenne) ) * Maverick18 ([@Aditya-Shandilya1182](https://github.com/Aditya-Shandilya1182) ) * Michael Bolger ([@mbbolger](https://github.com/mbbolger) ) * Miguel Cárdenas ([@miguelcsx](https://github.com/miguelcsx) ) * Mohamed Rezk ([@mohamedrezk122](https://github.com/mohamedrezk122) ) * Mridul Seth ([@MridulS](https://github.com/MridulS) ) * Orion Sehn ([@OrionSehn](https://github.com/OrionSehn) ) * Orion Sehn ([@OrionSehn-personal](https://github.com/OrionSehn-personal) ) * Raj Pawar ([@Raj3110](https://github.com/Raj3110) ) * Rick Ratzel ([@rlratzel](https://github.com/rlratzel) ) * Ross Barnowski ([@rossbar](https://github.com/rossbar) ) * Sanchit Ram Arvind ([@sanchitram1](https://github.com/sanchitram1) ) * Sebastiano Vigna ([@vigna](https://github.com/vigna) ) * Till Hoffmann ([@tillahoffmann](https://github.com/tillahoffmann) ) * Woojin Jung ([@WoojinJung-04](https://github.com/WoojinJung-04) ) \_These lists are automatically generated, and may not be complete or may contain duplicates.\_ On this page --- # Dinitz’s Algorithm and Applications — NetworkX Notebooks [Skip to main content](#main-content) Back to top Ctrl+K [![NetworkX Notebooks - Home](../../../_static/networkx_banner.svg) ![NetworkX Notebooks - Home](../../../_static/networkx_banner.svg)](../../../index.html) * [GitHub](https://github.com/networkx/nx-guides/ "GitHub") Search Ctrl+K * [![Binder logo](../../../_static/images/logo_binder.svg)Binder](https://mybinder.org/v2/gh/networkx/nx-guides/main?urlpath=tree/site/content/algorithms/flow/dinitz_alg.md "Launch on Binder") * [Repository](https://github.com/networkx/nx-guides "Source repository") * [Suggest edit](https://github.com/networkx/nx-guides/edit/main/site/content/algorithms/flow/dinitz_alg.md "Suggest edit") * [Open issue](https://github.com/networkx/nx-guides/issues/new?title=Issue%20on%20page%20%2Fcontent/algorithms/flow/dinitz_alg.html&body=Your%20issue%20content%20here. "Open an issue") * [.ipynb](../../../_sources/content/algorithms/flow/dinitz_alg.ipynb "Download notebook file") * [.md](../../../_sources/content/algorithms/flow/dinitz_alg.md "Download source file") * .pdf Dinitz’s Algorithm and Applications =================================== Contents -------- Dinitz’s Algorithm and Applications[#](#dinitz-s-algorithm-and-applications "Link to this heading") ==================================================================================================== In this tutorial, we will explore the maximum flow problem [\[1\]](#id3) and Dinitz’s algorithm [\[2\]](#id4) , which is implemented at [`algorithms/flow/dinitz_alg.py`](https://github.com/networkx/networkx/blob/main/networkx/algorithms/flow/dinitz_alg.py) in NetworkX. We will also see how it can be used to solve some interesting problems. Import packages[#](#import-packages "Link to this heading") ------------------------------------------------------------ import networkx as nx import numpy as np import matplotlib.pyplot as plt import PIL import math from copy import deepcopy from collections import deque Maximum flow problem[#](#maximum-flow-problem "Link to this heading") ---------------------------------------------------------------------- ### Motivation[#](#motivation "Link to this heading") Let’s say you want to send your friend some data as soon as possible, but the only way of communication/sending data between you two is through a peer-to-peer network. An interesting thing about this peer-to-peer network is that it allows you to send data along the paths you specify with certain limits on the sizes of data per second that you can send between a pair of nodes in this network. G \= nx.read\_gml("data/example\_graph.gml") \# Extract info about node position from graph (for visualization) pos \= {k: np.asarray(v) for k, v in G.nodes(data\="pos")} label\_pos \= deepcopy(pos) label\_pos\["s"\]\[0\] \= \-1.15 label\_pos\["t"\]\[0\] \= 1.20 labels \= {"s": "You", "t": "Friend"} fig, ax \= plt.subplots(figsize\=(16, 8)) nx.draw\_networkx\_edges(G, pos\=pos, ax\=ax, min\_source\_margin\=20, min\_target\_margin\=20) nx.draw\_networkx\_labels(G, label\_pos, labels\=labels, ax\=ax, font\_size\=16) ax.set\_xlim(\[\-1.4, 1.4\]) ax.axis("off") \# Spruce up the image with computer icons to represent the nodes tr\_figure \= ax.transData.transform tr\_axes \= fig.transFigure.inverted().transform icon\_size \= abs(np.diff(ax.get\_xlim())) \* 0.015 icon\_center \= icon\_size / 2 icon \= PIL.Image.open("images/computer\_black\_144x144.png") for n in G.nodes: xf, yf \= tr\_figure(pos\[n\]) xa, ya \= tr\_axes((xf, yf)) a \= plt.axes(\[xa \- icon\_center, ya \- icon\_center, icon\_size, icon\_size\]) a.imshow(icon) a.axis("off") ![../../../_images/910e526e5f140a67fc509d87303065da477f528a86fb8dcf61b17fa274582955.png](../../../_images/910e526e5f140a67fc509d87303065da477f528a86fb8dcf61b17fa274582955.png) So how shall you plan the paths of the data packets to send them in the least amount of time? Note that here we can divide the data into small data packets and send it across the network and the receiver will be able to rearrange the data packets to reconstruct the original data. ### Formalization[#](#formalization "Link to this heading") So how can we model this problem in terms of graphs? Let’s say \\(N=(V, E)\\) represents this peer-to-peer network with \\(V\\) as the set of nodes where nodes are computers and \\(E\\) as the set of edges where edge \\(uv \\in E\\) if there is a connection from node \\(u\\) to node \\(v\\) across which we can send data. There are also 2 special nodes, the first one is you (node \\(s\\)) and the second one is your friend (node \\(t\\)). We also name them the _**source**_ and _**sink**_ nodes respectively. fig, ax \= plt.subplots(figsize\=(16, 8)) \# Color source and sink node node\_colors \= \["skyblue" if n in {"s", "t"} else "lightgray" for n in G.nodes\] \# Draw graph nx.draw(G, pos, ax\=ax, node\_color\=node\_colors, with\_labels\=True) nx.draw\_networkx\_labels(G, label\_pos, labels\=labels, ax\=ax, font\_size\=16) ax.set\_xlim(\[\-1.4, 1.4\]); ![../../../_images/37e1fa20d7db3eb9fd76209f2c72ca4a020606d3dd21b59c68353e13ec510c3b.png](../../../_images/37e1fa20d7db3eb9fd76209f2c72ca4a020606d3dd21b59c68353e13ec510c3b.png) Now say that node \\(u\\) and node \\(v\\) are connected and the maximum data per second that you can send from node \\(u\\) to node \\(v\\) is \\(c\_{uv}\\) and let’s call this the capacity of the edge \\(uv\\). fig, ax \= plt.subplots(figsize\=(16, 8)) \# Label capacities capacities \= {(u, v): c for u, v, c in G.edges(data\="capacity")} \# Draw graph nx.draw(G, pos, ax\=ax, node\_color\=node\_colors, with\_labels\=True) nx.draw\_networkx\_edge\_labels(G, pos, edge\_labels\=capacities, ax\=ax) nx.draw\_networkx\_labels(G, label\_pos, labels\=labels, ax\=ax, font\_size\=16) ax.set\_xlim(\[\-1.4, 1.4\]); ![../../../_images/099f9aafbd8aafc28f9b3870364be05415441385b2529f6ad5c10ca531b4e35a.png](../../../_images/099f9aafbd8aafc28f9b3870364be05415441385b2529f6ad5c10ca531b4e35a.png) So before we go ahead and plan the paths on which we will be sending the data packets, we need some ways to represent or plan on the network. Observe that any plan will have to take up some capacity of the edges, so we can represent the plan by the values of the capacity taken by it for each edge in E, let’s call the plan as **flow**. Formally, we can define flow as \\(f: E \\to \\mathbb{R}\\) i.e. a mapping from edges \\(E\\) to real numbers denoting that we are sending data at rate \\(f(uv)\\) through edge \\(uv\\in E\\). Note that for this plan to be a valid plan, it must satisfy the following constraints: * **Capacity constraint:** The data rate at which we are sending data from any node shouldn’t exceed its capacity, formally \\(f\_{uv} \\le c\_{uv}\\) * **Conservation of flow:** Rate at which data is sent to a node is same as the rate at which the node is sending data to other nodes, except for the source \\(s\\) and sink \\(t\\) nodes. Formally \\(\\sum\\limits\_{u|(u,v) \\in E}f\_{u,v} = \\sum\\limits\_{w|(v,w) \\in E}f\_{v,w} \\) for \\(v\\in V\\backslash \\{s,t\\}\\) def check\_valid\_flow(G, flow, source\_node, target\_node): H \= nx.DiGraph() H.add\_edges\_from(flow.keys()) for (u, v), f in flow.items(): capacity \= G\[u\]\[v\]\["capacity"\] H\[u\]\[v\]\["label"\] \= f"{f}/{capacity}" \# Capacity constraint if f \> G\[u\]\[v\]\["capacity"\]: H\[u\]\[v\]\["edgecolor"\] \= "red" print(f"Invalid flow: capacity constraint violated for edge ({u!r}, {v!r})") \# Conservation of flow if v not in {source\_node, target\_node}: incoming\_flow \= sum( flow\[(i, v)\] if (i, v) in flow else 0 for i in G.predecessors(v) ) outgoing\_flow \= sum( flow\[(v, o)\] if (v, o) in flow else 0 for o in G.successors(v) ) if not math.isclose(incoming\_flow, outgoing\_flow): print(f"Invalid flow: flow conservation violated at node {v}") H.nodes\[v\]\["color"\] \= "red" return H def visualize\_flow(flow\_graph): """Visualize flow returned by the \`check\_valid\_flow\` funcion.""" fig, ax \= plt.subplots(figsize\=(15, 9)) \# Draw the full graph for reference nx.draw( G, pos, ax\=ax, node\_color\=node\_colors, edge\_color\="lightgrey", with\_labels\=True ) \# Draw the example flow on top flow\_nc \= \[\ "skyblue" if n in {"s", "t"} else flow\_graph.nodes\[n\].get("color", "lightgrey")\ for n in flow\_graph\ \] flow\_ec \= \[flow\_graph\[u\]\[v\].get("edgecolor", "black") for u, v in flow\_graph.edges\] edge\_labels \= {(u, v): lbl for u, v, lbl in flow\_graph.edges(data\="label")} nx.draw(flow\_graph, pos, ax\=ax, node\_color\=flow\_nc, edge\_color\=flow\_ec) nx.draw\_networkx\_edge\_labels(G, pos, edge\_labels\=edge\_labels, ax\=ax); Example of valid flow: example\_flow \= { ("s", "a"): 20, ("a", "e"): 15, ("e", "i"): 15, ("i", "t"): 15, ("a", "h"): 5, ("h", "l"): 5, ("l", "t"): 5, } flow\_graph \= check\_valid\_flow(G, example\_flow, "s", "t") visualize\_flow(flow\_graph) ![../../../_images/6ce8a7f9551814f75913ec19563057047c9cf463718e7099313bd2df72d8d4f2.png](../../../_images/6ce8a7f9551814f75913ec19563057047c9cf463718e7099313bd2df72d8d4f2.png) Example of invalid flow: example\_flow \= { ("s", "a"): 30, ("a", "e"): 25, ("e", "i"): 15, ("i", "t"): 15, ("a", "h"): 5, ("h", "l"): 5, ("l", "t"): 5, } flow\_graph \= check\_valid\_flow(G, example\_flow, "s", "t") Invalid flow: capacity constraint violated for edge ('s', 'a') Invalid flow: flow conservation violated at node e visualize\_flow(flow\_graph) ![../../../_images/eb53d583200c8d2a1234b587ab0872130c246a4a7a204e2faa1b5d56e8c8feba.png](../../../_images/eb53d583200c8d2a1234b587ab0872130c246a4a7a204e2faa1b5d56e8c8feba.png) Red color edges don’t satisfy capacity constraint and red color nodes don’t satisfy the conservation of flow. _So if we use this plan/flow to send data then at what rate will we be sending the data to friend?_ To answer this we need to observe that any data that the sink node \\(t\\) will receive will be from its neighbors so if we sum over the data rates from plan/flow from those neighbors to the sink node we shall get the total data rate at which \\(t\\) will be receiving the data. Formally we can say that the **value of the flow** is \\(|f|=\\sum\\limits\_{u|(u,t) \\in E}f\_{u,t}\\). Also note that since flow is conservative \\(|f|\\) would also be equal to \\(\\sum\\limits\_{u|(s,u) \\in E}f\_{s,u}\\). Remember our goal was to maximize the rate at which the data is being sent to our friend, which is the same as maximizing the flow value \\(|f|\\). This is the definition of the **Maximum Flow Problem**. Dinitz’s algorithm[#](#dinitz-s-algorithm "Link to this heading") ------------------------------------------------------------------ Before understanding how Dinitz’s algorithm works and its steps let’s define some terms. ### Residual Capacity & Graph[#](#residual-capacity-graph "Link to this heading") If we send \\(f\_{uv}\\) flow through edge \\(uv\\) with capacity \\(c\_{uv}\\), then we define residual capacity by \\(g\_{uv}=c\_{uv}-f\_{uv}\\) and residual network by \\(N'\\) which only considers the edges of \\(N\\) if they have non-zero residual capacity. def residual\_graph(G, flow): H \= G.copy() for (u, v), f in flow.items(): capacity \= G\[u\]\[v\]\["capacity"\] if f \> G\[u\]\[v\]\["capacity"\]: raise ValueError(f"Flow {f} exceeds the capacity of edge {u!r}\->{v!r}.") H\[u\]\[v\]\["capacity"\] \-= f if H.has\_edge(v, u): H\[v\]\[u\]\["capacity"\] += f else: H.add\_edge(v, u, capacity\=f, etype\="rev") return H def draw\_residual\_graph(R, ax\=None): """Visualize residual graph returned by \`residual\_graph\`.""" if not ax: fig, ax \= plt.subplots(figsize\=(15, 9)) ax.axis("off") \# Draw nodes nx.draw\_networkx\_nodes(R, pos, node\_color\=node\_colors) nx.draw\_networkx\_labels(R, pos) \# Categorize edges by their capacity and whether they were added by \# residual\_graph orig\_edges, zero\_edges, rev\_edges \= \[\], \[\], \[\] for u, v, data in R.edges(data\=True): if data.get("etype") \== "rev": rev\_edges.append((u, v)) elif data\["capacity"\] \== 0: zero\_edges.append((u, v)) else: orig\_edges.append((u, v)) \# Draw edges nx.draw\_networkx\_edges(R, pos, edgelist\=orig\_edges) nx.draw\_networkx\_edges( R, pos, edgelist\=rev\_edges, edge\_color\="goldenrod", connectionstyle\="arc3,rad=0.2", ) nx.draw\_networkx\_edges( R, pos, edgelist\=zero\_edges, style\="--", edge\_color\="lightgrey" ) \# Label edges by capacity rv \= set(rev\_edges) fwd\_caps \= {(u, v): c for u, v, c in R.edges(data\="capacity") if (u, v) not in rv} rev\_caps \= {(u, v): c for u, v, c in R.edges(data\="capacity") if (u, v) in rv} nx.draw\_networkx\_edge\_labels(R, pos, edge\_labels\=fwd\_caps, label\_pos\=0.667) nx.draw\_networkx\_edge\_labels( R, pos, edge\_labels\=rev\_caps, label\_pos\=0.667, font\_color\="goldenrod" ) Example flow: example\_flow \= { ("s", "a"): 15, ("a", "e"): 15, ("e", "i"): 15, ("i", "t"): 15, } visualize\_flow(check\_valid\_flow(G, example\_flow, "s", "t")) ![../../../_images/129b4c62306fbd65f58801da36016dcec83b1252926776d1caff65af0ede37b4.png](../../../_images/129b4c62306fbd65f58801da36016dcec83b1252926776d1caff65af0ede37b4.png) This is the residual network for the flow shown above: R \= residual\_graph(G, example\_flow) draw\_residual\_graph(R) ![../../../_images/438b644d3d82fab2ca0b9198465a72165105a48de220967a64afd516d92f02d8.png](../../../_images/438b644d3d82fab2ca0b9198465a72165105a48de220967a64afd516d92f02d8.png) Note: In residual network we consider both the \\(uv\\) and \\(vu\\) edges if any of them is in \\(N\\) ### Level Network[#](#level-network "Link to this heading") The level network is a subgraph of the residual network which we get when we apply [BFS](https://en.wikipedia.org/wiki/Breadth-first_search) from source node \\(s\\) considering only the edges for which we have \\(c\_{uv}-f\_{uv}>0\\) in the residual network and divide the nodes into levels then we only consider the edges to be in the level network \\(L\\) which connect nodes of 2 different levels \# Mapping between node level and color for visualization level\_colors \= { 1: "aqua", 2: "lightgreen", 3: "yellow", 4: "orange", 5: "lightpink", 6: "violet", } def level\_bfs(R, flow, source\_node, target\_node): """BFS to construct the level network from residual network for given flow.""" parents, level \= {}, {} queue \= deque(\[source\_node\]) level\[source\_node\] \= 0 while queue: if target\_node in parents: break u \= queue.popleft() for v in R.successors(u): if (v not in parents) and (R\[u\]\[v\]\["capacity"\] \> 0): parents\[v\] \= u level\[v\] \= level\[u\] + 1 queue.append(v) return parents, level def draw\_level\_network(R, parents, level, background\=False): fig, ax \= plt.subplots(figsize\=(15, 9)) ax.axis("off") \# Draw nodes nodelist \= list(level.keys()) if background: level\_nc \= "lightgrey" else: level\_nc \= \[level\_colors\[l\] for l in level.values()\] level\_nc\[0\] \= level\_nc\[\-1\] \= "skyblue" nx.draw\_networkx\_nodes(R, pos, nodelist\=nodelist, node\_color\=level\_nc) if not background: nx.draw\_networkx\_labels(R, pos) \# Draw edges fwd\_edges \= \[(v, u) for u, v in parents.items() if (v, u) in G.edges\] labels \= {(u, v): R\[u\]\[v\]\["capacity"\] for u, v in fwd\_edges} ec \= "lightgrey" if background else "black" nx.draw\_networkx\_edges(R, pos, edgelist\=fwd\_edges, edge\_color\=ec) if not background: nx.draw\_networkx\_edge\_labels(R, pos, edge\_labels\=labels, label\_pos\=0.667) rev\_edges \= \[(v, u) for u, v in parents.items() if (v, u) not in G.edges\] labels \= {(u, v): R\[u\]\[v\]\["capacity"\] for u, v in rev\_edges} ec \= "lightgrey" if background else "goldenrod" nx.draw\_networkx\_edges( R, pos, edgelist\=rev\_edges, connectionstyle\="arc3,rad=0.2", edge\_color\=ec ) if not background: nx.draw\_networkx\_edge\_labels( R, pos, edge\_labels\=labels, label\_pos\=0.667, font\_color\="goldenrod" ) parents, level \= level\_bfs(R, example\_flow, "s", "t") draw\_level\_network(R, parents, level) ![../../../_images/fd82043b583ff3349df86a51d31b3a4e227cf1a0338f7585fed45aaf2a095002.png](../../../_images/fd82043b583ff3349df86a51d31b3a4e227cf1a0338f7585fed45aaf2a095002.png) Note that if sink node \\(t\\) is not reachable from the source node \\(s\\) that means that no more flow can be pushed through the residual network. ### Augmenting Path & Flow[#](#augmenting-path-flow "Link to this heading") An _augmenting path_ \\(P\\) is a path from source node \\(s\\) to sink node \\(t\\) such that all the edges on the path have positive residual capacity i.e. \\(g\_{uv}>0\\) for \\(uv \\in P\\). An _augmenting flow_ \\(\\alpha\\) for the path \\(P\\) is the minimum value of the residual flow across all the edges of \\(P\\). i.e. \\(\\alpha = min\\{g\_{uv}, uv \\in P\\}\\). And by augmenting the flow along path \\(P\\) we mean that reduce the residual capacities of the edges in path \\(P\\) by \\(\\alpha\\) which will leave at least one of the edges on the residual network with zero residual capacity. We find augmenting paths by applying [DFS](https://en.wikipedia.org/wiki/Depth-first_search) on the Level network \\(L\\). def aug\_path\_dfs(parents, flow, source\_node, target\_node): """Build a path using DFS starting from the target\_node""" path \= \[\] u \= target\_node f \= 3 \* max(flow.values()) \# Initialize flow to large value while u != source\_node: path.append(u) v \= parents\[u\] f \= min(f, R.pred\[u\]\[v\]\["capacity"\] \- flow.get((u, v), 0)) u \= v path.append(source\_node) \# Augment the flow along the path found return path, f Augmenting path before augmenting: path, min\_resid\_flow \= aug\_path\_dfs(parents, example\_flow, "s", "t") \# Visualize draw\_level\_network(R, parents, level, background\=True) \# Level graph in the background nc \= \[level\_colors\[level\[n\]\] for n in path\] el \= \[(v, u) for u, v in nx.utils.pairwise(path)\] nx.draw(R, pos, nodelist\=path, edgelist\=el, node\_color\=nc, with\_labels\=True) edgelabels \= {(u, v): R\[u\]\[v\]\["capacity"\] for u, v in el} nx.draw\_networkx\_edge\_labels(R, pos, edge\_labels\=edgelabels, label\_pos\=0.667); ![../../../_images/486a2c54445c45b09870406d32762a17be6d4ae2c762e5decc36cb436c88bf04.png](../../../_images/486a2c54445c45b09870406d32762a17be6d4ae2c762e5decc36cb436c88bf04.png) Augmenting path after augmenting: \# Apply the minimum flow along the augmenting path aug\_flow \= {(v, u): min\_resid\_flow for u, v in nx.utils.pairwise(path)} \# Visualize the augmented flow along the path draw\_level\_network(R, parents, level, background\=True) aug\_path \= residual\_graph(R.subgraph(path), aug\_flow) \# Node ordering in the subgraph can be different than \`path\` nodes \= list(aug\_path.nodes) node\_colors \= \[level\_colors\[level\[n\]\] for n in nodes\] node\_colors\[nodes.index("s")\] \= node\_colors\[nodes.index("t")\] \= "skyblue" draw\_residual\_graph(aug\_path, ax\=plt.gca()) ![../../../_images/9c73062383f09a0e24be35cc7d69768a9e7b76edaa56f39bcab5e1bcd1194356.png](../../../_images/9c73062383f09a0e24be35cc7d69768a9e7b76edaa56f39bcab5e1bcd1194356.png) Resulting new residual Network: R \= residual\_graph(R, aug\_flow) \# Original color scheme for residual graph node\_colors \= \["skyblue" if n in {"s", "t"} else "lightgray" for n in R.nodes\] draw\_residual\_graph(R) ![../../../_images/ec519954f81e6ce1aa66d85e70bbcd26f8d60bf1668d3180cc787d592ca2fc7a.png](../../../_images/ec519954f81e6ce1aa66d85e70bbcd26f8d60bf1668d3180cc787d592ca2fc7a.png) Each of the above steps plays a role in Dinitz’s algorithm for finding the maximum flow in a network, summarized below. ### Algorithm[#](#algorithm "Link to this heading") 1. Initialize a flow with zero value, \\(f\_{uv}=0\\) 2. Construct a residual network \\(N'\\) from that flow 3. Find the level network \\(L\\) using BFS, if \\(t\\) is not in the level network then break and output the flow 4. Find an augmenting path \\(P\\) in level network \\(L\\) 5. Augment the flow along the edges of path \\(P\\) which will give a new residual network 6. Repeat from point 3 with new residual network \\(N'\\) Maximum flow in NetworkX[#](#maximum-flow-in-networkx "Link to this heading") ------------------------------------------------------------------------------ In the previous section, we decomposed the Dinitz’s algorithm into smaller steps to better understand the algorithm as a whole. In practice however, there’s no need to implement all these steps yourself! NetworkX provides an implementation of Dinitz’s algorithm: [nx.flow.dinitz](https://networkx.org/documentation/latest/reference/algorithms/generated/networkx.algorithms.flow.dinitz.html) . `nx.flow.dinitz` includes several features in addition to those described above. For example, the `cutoff` keyword argument can be used to prematurely terminate the Dinitz’s algorithm once the desired flow value is reached. Let’s try out NetworkX’s implementation of Dinitz’s algorithm on our example network, `G`. \# Maximum flow values to find. Note the final value of \`None\` which indicates \# the algorithm should run to completion, finding the true maximum flow cutoff\_list \= \[5, 10, 15, 20, 25, 30, 35, None\] fig, axes \= plt.subplots(4, 2, figsize\=(20, 30)) node\_colors \= \["skyblue" if n in {"s", "t"} else "lightgray" for n in G.nodes\] for cutoff, ax in zip(cutoff\_list, axes.ravel()): \# calculating the maximum flow with the cutoff value R \= nx.flow.dinitz(G, s\="s", t\="t", capacity\="capacity", cutoff\=cutoff) \# coloring and labeling edges depending on if they have non-zero flow value or not edge\_colors \= \["lightgray" if R\[u\]\[v\]\["flow"\] \== 0 else "black" for u, v in G.edges\] edge\_labels \= { (u, v): f"{R\[u\]\[v\]\['flow'\]}/{G\[u\]\[v\]\['capacity'\]}" for u, v in G.edges if R\[u\]\[v\]\["flow"\] != 0 } \# drawing the network nx.draw\_networkx\_nodes(G, pos\=pos, ax\=ax, node\_size\=500, node\_color\=node\_colors) nx.draw\_networkx\_labels(G, pos\=pos, ax\=ax, font\_size\=14) nx.draw\_networkx\_edges(G, pos\=pos, ax\=ax, edge\_color\=edge\_colors) nx.draw\_networkx\_edge\_labels( G, pos\=pos, ax\=ax, edge\_labels\=edge\_labels, font\_size\=14 ) ax.set\_title( f"Cutoff value = {cutoff}; Max Flow = {R.graph\['flow\_value'\]}", size\=22, ) fig.tight\_layout() ![../../../_images/120ecc4acd752edabb2fa4b1ec1f015eda6459d0442da6c1e9689ddc9b5c84f7.png](../../../_images/120ecc4acd752edabb2fa4b1ec1f015eda6459d0442da6c1e9689ddc9b5c84f7.png) Note: Iteration are stopped if the maximum flow found so far exceeds the cutoff value Applications[#](#applications "Link to this heading") ------------------------------------------------------ There are many other problems which can be reduced to Maximum flow problem, for example: * [Maximum Bipartite Matching](https://en.wikipedia.org/wiki/Matching_(graph_theory)) * [Assignment Problem](https://en.wikipedia.org/wiki/Assignment_problem) * [Transportation Problem](https://en.wikipedia.org/wiki/Transportation_theory_(mathematics)) and many others. Note that even though Dinitz works in \\(O(n^2m)\\) strongly polynomial time, i.e. to say it doesn’t depend on the value of flow. It is noteworthy that its performance of bipartite graphs is especially fast being \\(O(\\sqrt n m)\\) time, where \\(n = |V|\\) & \\(m = |E|\\). Let’s consider the example of shipping packages from warehouse to customers through some intermediate shipping points, and we can only ship limited number of packages through an intermediate shipping point in a day. So how to assign intermediate shipping point to customer so that maximum number of packages are shipped in a day? ![image:shipping problem eg](../../../_images/shipping-problem.png) Number below each intermediate shipping point is the maximum number of shipping that it can do in a day, and if edge connects an intermdiate shipping point and a customer only then we can send the package from that shipping point to that customer. Note that the warehouse node is named as \\(W\\), intermediate shipping points as \\(lw1, lw2, lw3\\), and customers as \\(c1,c2...c20\\). \# Load data B \= nx.read\_gml("data/shipping\_graph.gml") pos \= {k: np.asarray(v) for k, v in B.nodes(data\="pos")} \# drawing the loaded graph node\_colors \= \["skyblue" if u \== "W" else "lightgray" for u in B.nodes\] plt.figure(figsize\=(20, 10)) nx.draw( B, pos\=pos, node\_color\=node\_colors, with\_labels\=True, arrowsize\=10, node\_size\=800 ) ![../../../_images/0c6dde4a5cb3025a0725077648f873395d5b2d311117f9d80070a963b09d685a.png](../../../_images/0c6dde4a5cb3025a0725077648f873395d5b2d311117f9d80070a963b09d685a.png) \# maximum shipping capacities {u: B.nodes\[u\]\["maximum\_shippings"\] for u in \["lw1", "lw2", "lw3"\]} {'lw1': 8, 'lw2': 5, 'lw3': 6} Let’s add a pseudo node \\(T\\) denoting the ultimate sink node and add edges from \\(ci \\to T\\), \\(i\\in\\{1,2,...,20\\}\\). Note that shipping any more than the maximum number of packages that any of \\(lwi\\), \\(i\\in\\{1,2,3\\}\\) can ship on that day is useless. So we can transfer that maximum number of shipping to a maximum capacity of the edges \\(W\\to lwi\\), \\(i\\in\\{1,2,3\\}\\) and for all other edges, we can assign its capacity as 1 we only need to do one shipment per customer. Note: We have already assigned the position to node \\(T\\) in `pos` which was loaded earlier. \# adding node T and edges to T from c1,c2,...c20 B.add\_node("T") pos\["T"\] \= np.array(\[0.97, 0.0\]) B.add\_edges\_from((f"c{i}", "T") for i in range(1, 21)) \# adding capacities from W to lw1, lw2, lw3 for u in \["lw1", "lw2", "lw3"\]: B\["W"\]\[u\]\["capacity"\] \= B.nodes\[u\]\["maximum\_shippings"\] \# adding capacities as 1 for all other edges except edges from W for u, v in B.edges: if u != "W": B\[u\]\[v\]\["capacity"\] \= 1 \# assign colors and labels to nodes based on their type node\_colors \= \["skyblue" if u in {"W", "T"} else "lightgray" for u in B.nodes\] \# calculating the maximum flow with the cutoff value R \= nx.flow.dinitz(B, s\="W", t\="T", capacity\="capacity") \# coloring and labeling edges depending on if they have non-zero flow value or not edge\_colors \= \["0.8" if R\[u\]\[v\]\["flow"\] \== 0 else "0" for u, v in B.edges\] \# drawing the network plt.figure(figsize\=(20, 10)) nx.draw\_networkx\_nodes(B, pos\=pos, node\_size\=400, node\_color\=node\_colors) nx.draw\_networkx\_labels(B, pos\=pos, font\_size\=8) nx.draw\_networkx\_edges(B, pos\=pos, edge\_color\=edge\_colors) plt.title(f"Max Flow = {R.graph\['flow\_value'\]}", size\=12) plt.axis("off") plt.show() ![../../../_images/87a24a69ed83351fb420c8f780b8730ff967f1d5cc9246de9fa68017891a0833.png](../../../_images/87a24a69ed83351fb420c8f780b8730ff967f1d5cc9246de9fa68017891a0833.png) Above we can see a matching of intermediate shipping points and customers which gives the maximum shipping in a day. References[#](#references "Link to this heading") -------------------------------------------------- Contents --- # Software for Complex Networks — NetworkX 3.5rc0.dev0 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Choose version Software for Complex Networks[#](#software-for-complex-networks "Link to this heading") ======================================================================================== Release: 3.5rc0.dev0 Date: Mar 01, 2025 NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. It provides: * tools for the study of the structure and dynamics of social, biological, and infrastructure networks; * a standard programming interface and graph implementation that is suitable for many applications; * a rapid development environment for collaborative, multidisciplinary projects; * support for algorithm acceleration and additional features through third-party backends; * an interface to existing numerical algorithms and code written in C, C++, and FORTRAN; and * the ability to painlessly work with large nonstandard data sets. With NetworkX you can load and store networks in standard and nonstandard data formats, generate many types of random and classic networks, analyze network structure, build network models, design new network algorithms, draw networks, and much more. Citing[#](#citing "Link to this heading") ------------------------------------------ To cite NetworkX please use the following publication: Aric A. Hagberg, Daniel A. Schult and Pieter J. Swart, [“Exploring network structure, dynamics, and function using NetworkX”](http://conference.scipy.org.s3-website-us-east-1.amazonaws.com/proceedings/scipy2008/paper_2/) , in [Proceedings of the 7th Python in Science Conference (SciPy2008)](http://conference.scipy.org.s3-website-us-east-1.amazonaws.com/proceedings/scipy2008/index.html) , Gäel Varoquaux, Travis Vaught, and Jarrod Millman (Eds), (Pasadena, CA USA), pp. 11–15, Aug 2008 [PDF](http://conference.scipy.org.s3-website-us-east-1.amazonaws.com/proceedings/scipy2008/paper_2/full_text.pdf) [BibTeX](http://conference.scipy.org.s3-website-us-east-1.amazonaws.com/proceedings/scipy2008/paper_2/reference.bib) Audience[#](#audience "Link to this heading") ---------------------------------------------- The audience for NetworkX includes mathematicians, physicists, biologists, computer scientists, and social scientists. Good reviews of the science of complex networks are presented in Albert and Barabási [\[BA02\]](#ba02) , Newman [\[Newman03\]](#newman03) , and Dorogovtsev and Mendes [\[DM03\]](#dm03) . See also the classic texts [\[Bollobas01\]](#bollobas01) , [\[Diestel97\]](#diestel97) and [\[West01\]](#west01) for graph theoretic results and terminology. For basic graph algorithms, we recommend the texts of Sedgewick (e.g., [\[Sedgewick01\]](#sedgewick01) and [\[Sedgewick02\]](#sedgewick02) ) and the survey of Brandes and Erlebach [\[BE05\]](#be05) . Python[#](#python "Link to this heading") ------------------------------------------ Python is a powerful programming language that allows simple and flexible representations of networks as well as clear and concise expressions of network algorithms. Python has a vibrant and growing ecosystem of packages that NetworkX uses to provide more features such as numerical linear algebra and drawing. In order to make the most out of NetworkX you will want to know how to write basic programs in Python. Among the many guides to Python, we recommend the [Python documentation](https://docs.python.org/3/) and the text by Alex Martelli [\[Martelli03\]](#martelli03) . License[#](#license "Link to this heading") -------------------------------------------- NetworkX is distributed with the 3-clause BSD license. Copyright (C) 2004\-2024, NetworkX Developers Aric Hagberg Dan Schult Pieter Swart All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: \* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. \* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. \* Neither the name of the NetworkX Developers nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Bibliography[#](#bibliography "Link to this heading") ------------------------------------------------------ \[[BA02](#id1)\ \] R. Albert and A.-L. Barabási, “Statistical mechanics of complex networks”, Reviews of Modern Physics, 74, pp. 47-97, 2002. [https://arxiv.org/abs/cond-mat/0106096](https://arxiv.org/abs/cond-mat/0106096) \[[Bollobas01](#id4)\ \] B. Bollobás, “Random Graphs”, Second Edition, Cambridge University Press, 2001. \[[BE05](#id9)\ \] U. Brandes and T. Erlebach, “Network Analysis: Methodological Foundations”, Lecture Notes in Computer Science, Volume 3418, Springer-Verlag, 2005. \[[Diestel97](#id5)\ \] R. Diestel, “Graph Theory”, Springer-Verlag, 1997. [http://diestel-graph-theory.com/index.html](http://diestel-graph-theory.com/index.html) \[[DM03](#id3)\ \] S.N. Dorogovtsev and J.F.F. Mendes, “Evolution of Networks”, Oxford University Press, 2003. \[[Martelli03](#id10)\ \] A. Martelli, “Python in a Nutshell”, O’Reilly Media Inc, 2003. \[[Newman03](#id2)\ \] M.E.J. Newman, “The Structure and Function of Complex Networks”, SIAM Review, 45, pp. 167-256, 2003. [http://epubs.siam.org/doi/abs/10.1137/S003614450342480](http://epubs.siam.org/doi/abs/10.1137/S003614450342480) \[[Sedgewick02](#id8)\ \] R. Sedgewick, “Algorithms in C: Parts 1-4: Fundamentals, Data Structure, Sorting, Searching”, Addison Wesley Professional, 3rd ed., 2002. \[[Sedgewick01](#id7)\ \] R. Sedgewick, “Algorithms in C, Part 5: Graph Algorithms”, Addison Wesley Professional, 3rd ed., 2001. \[[West01](#id6)\ \] D. B. West, “Introduction to Graph Theory”, Prentice Hall, 2nd ed., 2001. On this page --- # Roadmap — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Roadmap[#](#roadmap "Link to this heading") ============================================ The roadmap is intended for larger, fundamental changes to the project that are likely to take months or years of developer time. Smaller-scoped items will continue to be tracked on our issue tracker. The scope of these improvements means that these changes may be controversial, are likely to involve significant discussion among the core development team, and may require the creation of one or more [Enhancement Proposals (NXEPs)](nxeps/nxep-0001.html#nxep) . Installation[#](#installation "Link to this heading") ------------------------------------------------------ We aim to make NetworkX as easy to install as possible. Some of our dependencies (e.g., graphviz) can be tricky to install. Other of our dependencies are easy to install on the CPython platform, but may be more involved on other platforms such as PyPy. Addressing these installation issues may involve working with the external projects. Sustainability[#](#sustainability "Link to this heading") ---------------------------------------------------------- We aim to reduce barriers to contribution, speed up pull request (PR) review, onboard new maintainers, and attract new developers to ensure the long-term sustainability of NetworkX. This includes: * improving continuous integration * making code base more approachable * creating new pathways beyond volunteer effort * growing maintainers and leadership * increasing diversity of developer community Performance[#](#performance "Link to this heading") ---------------------------------------------------- Speed improvements, lower memory usage, and the ability to parallelize algorithms are beneficial to most science domains and use cases. A first step may include implementing a benchmarking system using something like airspeed velocity ([https://asv.readthedocs.io/en/stable/](https://asv.readthedocs.io/en/stable/) ). It may also include review existing comparisons between NetworkX and other packages. Individual functions can be optimized for performance and memory use. We are also interested in exploring new technologies to accelerate code and reduce memory use. Before adopting any new technologies we will need to careful consider its impact on code readability and difficulty of building and installing NetworkX. For more information, see our [Mission and Values](values.html#mission-and-values) . Many functions can be trivially parallelized. But, we need to decide on an API and perhaps implement some helper code to make it consistent. Documentation[#](#documentation "Link to this heading") -------------------------------------------------------- We’d like to improve the content, structure, and presentation of the NetworkX documentation. Some specific goals include: * longer gallery examples * domain-specific documentation (NetworkX for Geneticists, NetworkX for Neuroscientists, etc.) * examples of how to use NetworkX with other packages Linear Algebra[#](#linear-algebra "Link to this heading") ---------------------------------------------------------- We would like to improve our linear algebra based algorithms. The code is old and needs review and refactoring. This would include investigating SciPy’s csgraph. It would also include deciding how to handle algorithms that have multiple implementations (e.g., some algorithms are implemented in Python, NumPy, and SciPy). NumPy has split its API from its execution engine with `__array_function__` and `__array_ufunc__`. This will enable parts of NumPy to accept distributed arrays (e.g. dask.array.Array) and GPU arrays (e.g. cupy.ndarray) that implement the ndarray interface. At the moment it is not yet clear which algorithms will work out of the box, and if there are significant performance gains when they do. Interoperability[#](#interoperability "Link to this heading") -------------------------------------------------------------- We’d like to improve interoperability with the rest of the scientific Python ecosystem. This includes projects we depend on (e.g., NumPy, SciPy, Pandas, Matplotlib) as well as ones we don’t (e.g., Geopandas). For example, we would also like to be able to seamlessly exchange graphs with other network analysis software. Another way to integrate with other scientific python ecosystem tools is to take on features from the other tools that are useful. And we should develop tools to ease use of NetworkX from within these other tools. Additional examples of interoperability improvements may include providing a more pandas-like interface for the `` `__getitem__` `` dunder function of node and edge views ([NXEP 2 — API design of view slices](nxeps/nxep-0002.html#nxep2) ). Also developing a universal method to represent a graph as a single sequence of `` `nodes_and_edges` `` objects that allow attribute dicts, nodes and edges as [discussed for graph generators](https://github.com/networkx/networkx/issues/3036) . Visualization[#](#visualization "Link to this heading") -------------------------------------------------------- Visualization is not a focus on NetworkX, but it is a major feature for many users. We need to enhance the drawing tools for NetworkX. On this page --- # Deprecations — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") Deprecations[#](#deprecations "Link to this heading") ====================================================== Policy[#](#policy "Link to this heading") ------------------------------------------ If the behavior of the library has to be changed, a deprecation cycle must be followed to warn users. A deprecation cycle is _not_ necessary when: * adding a new function, or * adding a new keyword argument to the _end_ of a function signature, or * fixing buggy behavior A deprecation cycle is necessary for _any breaking API change_, meaning a change where the function, invoked with the same arguments, would return a different result after the change. This includes: * changing the order of arguments or keyword arguments, or * adding arguments or keyword arguments to a function, or * changing the name of a function, class, method, etc., or * moving a function, class, etc. to a different module, or * changing the default value of a function’s arguments. Usually, our policy is to put in place a deprecation cycle over two minor releases (e.g., if a deprecation warning appears in 2.3, then the functionality should be removed in 2.5). For major releases we usually require that all deprecations have at least a 1-release deprecation cycle (e.g., if 3.0 occurs after 2.5, then all removed functionality in 3.0 should be deprecated in 2.5). Note that these 1- and 2-release deprecation cycles for major and minor releases is not a strict rule and in some cases, the developers can agree on a different procedure upon justification (like when we can’t detect the change, or it involves moving or deleting an entire function for example). Todo[#](#todo "Link to this heading") -------------------------------------- Make sure to review `networkx/conftest.py` after removing deprecated code. ### Version 3.5[#](#version-3-5 "Link to this heading") * Remove `all_triplets` from `algorithms/triads.py` * Remove `random_triad` from `algorithms/triad.py`. * Remove `d_separated` from `algorithms/d_separation.py`. * Remove `minimal_d_separator` from `algorithms/d_separation.py`. * Add `not_implemented_for("multigraph”)` decorator to `k_core`, `k_shell`, `k_crust` and `k_corona` functions. * Change `single_target_shortest_path_length` in `algorithms/shortest_path/unweighted.py` to return a dict. See #6527 * Change `shortest_path` in `algorithms/shortest_path/generic.py` to return a iterator. See #6527 * Remove `total_spanning_tree_weight` from `linalg/laplacianmatrix.py` * Remove `create` keyword argument from `nonisomorphic_trees` in `generators/nonisomorphic_trees`. ### Version 3.6[#](#version-3-6 "Link to this heading") * Remove `compute_v_structures` from `algorithms/dag.py`. * Remove `link` kwarg from `readwrite/json_graph/node_link.py`; Remove the `FutureWarning` re: the default value of `edges` and change the default value to `"edges"`. On this page --- # NetworkX 3.3 — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NetworkX 3.3[#](#networkx-3-3 "Link to this heading") ====================================================== Release date: 6 April 2024 Supports Python 3.10, 3.11, and 3.12. NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. For more information, please visit our [website](https://networkx.org/) and our [gallery of examples](../auto_examples/index.html#examples-gallery) . Please send comments and questions to the [networkx-discuss mailing list](http://groups.google.com/group/networkx-discuss) . API Changes[#](#api-changes "Link to this heading") ---------------------------------------------------- * Disallow negative number of nodes in `complete_multipartite_graph` ([#7057](https://github.com/networkx/networkx/pull/7057) ). * DEP: Deprecate the all\_triplets one-liner ([#7060](https://github.com/networkx/networkx/pull/7060) ). * \[A-star\] Added expansion pruning via cutoff if cutoff is provided ([#7073](https://github.com/networkx/networkx/pull/7073) ). * Make HITS raise exceptions consistent with power iterations ([#7084](https://github.com/networkx/networkx/pull/7084) ). * DEP: Deprecate random\_triad ([#7061](https://github.com/networkx/networkx/pull/7061) ). * Added feature modular graph product ([#7227](https://github.com/networkx/networkx/pull/7227) ). * ENH: Speed up common/non\_neighbors by using \_adj dict operations ([#7244](https://github.com/networkx/networkx/pull/7244) ). * Deprecate the `create` argument of `nonisomorphic_trees` ([#7316](https://github.com/networkx/networkx/pull/7316) ). * Improve total\_spanning\_tree\_weight ([#7100](https://github.com/networkx/networkx/pull/7100) ). * Update \_\_init\_\_.py ([#7320](https://github.com/networkx/networkx/pull/7320) ). * add \*\*kwargs to traveling\_salesman\_problem ([#7371](https://github.com/networkx/networkx/pull/7371) ). Enhancements[#](#enhancements "Link to this heading") ------------------------------------------------------ * Add Tadpole graph ([#6999](https://github.com/networkx/networkx/pull/6999) ). * \[A-star\] Added expansion pruning via cutoff if cutoff is provided ([#7073](https://github.com/networkx/networkx/pull/7073) ). * Implementation of \\(S^1\\) model ([#6858](https://github.com/networkx/networkx/pull/6858) ). * \[Feat\] Random expanders utilities ([#6761](https://github.com/networkx/networkx/pull/6761) ). * Compare graphs for generator functions when running tests with backend ([#7066](https://github.com/networkx/networkx/pull/7066) ). * Add Kirchhoff index / Effective graph resistance ([#6926](https://github.com/networkx/networkx/pull/6926) ). * Changed return types of shortest path methods to improve consistency ([#6584](https://github.com/networkx/networkx/pull/6584) ). * New PR for Fixes minimal d-separator function failing to handle cases where no d-separators exist ([#7019](https://github.com/networkx/networkx/pull/7019) ). * ENH : Provide non-normalized and normalized directed laplacian matrix calculation ([#7199](https://github.com/networkx/networkx/pull/7199) ). * feat: drop the use of node attribute “first\_nbr” in PlanarEmbedding ([#7202](https://github.com/networkx/networkx/pull/7202) ). * Add functions to compute Schultz and Gutman Index ([#3709](https://github.com/networkx/networkx/pull/3709) ). * Divisive community algorithms ([#5830](https://github.com/networkx/networkx/pull/5830) ). * Added feature modular graph product ([#7227](https://github.com/networkx/networkx/pull/7227) ). * ENH : added `sort_neighbors` to all functions in `depth_first_search.py` ([#7196](https://github.com/networkx/networkx/pull/7196) ). * New graph generator for the Kneser graph ([#7146](https://github.com/networkx/networkx/pull/7146) ). * Draw MultiDiGraph edges and labels qa7008 ([#7010](https://github.com/networkx/networkx/pull/7010) ). * Use github actions to run a comparison benchmark ([#7268](https://github.com/networkx/networkx/pull/7268) ). * BFS layout implementation ([#5179](https://github.com/networkx/networkx/pull/5179) ). * Add `max_level=` argument to `louvain_communities` to limit macro-iterations ([#6909](https://github.com/networkx/networkx/pull/6909) ). * Review and update `@nx._dispatchable` usage since 3.2.1 ([#7302](https://github.com/networkx/networkx/pull/7302) ). * Transmogrify `_dispatchable` objects into functions ([#7298](https://github.com/networkx/networkx/pull/7298) ). * fix: make `PlanarEmbedding.copy()` use `add_edges_from()` from parent (closes #7223) ([#7224](https://github.com/networkx/networkx/pull/7224) ). * Allow seed of np.random instance to exactly produce arbitrarily large integers ([#6869](https://github.com/networkx/networkx/pull/6869) ). * Improve total\_spanning\_tree\_weight ([#7100](https://github.com/networkx/networkx/pull/7100) ). * add seed to `nx.generate_random_paths` ([#7332](https://github.com/networkx/networkx/pull/7332) ). * Allow backends to implement `should_run` ([#7257](https://github.com/networkx/networkx/pull/7257) ). * Adding tree broadcasting algorithm in a new module ([#6928](https://github.com/networkx/networkx/pull/6928) ). * Option to include initial labels in `weisfeiler_lehman_subgraph_hashes` ([#6601](https://github.com/networkx/networkx/pull/6601) ). * Add better error message when trying to get edge that is not present ([#7245](https://github.com/networkx/networkx/pull/7245) ). * Make `is_negatively_weighted` dispatchable ([#7352](https://github.com/networkx/networkx/pull/7352) ). * Add option to hide or show tick labels ([#6018](https://github.com/networkx/networkx/pull/6018) ). * ENH: Cache graphs objects when converting to a backend ([#7345](https://github.com/networkx/networkx/pull/7345) ). Bug Fixes[#](#bug-fixes "Link to this heading") ------------------------------------------------ * Fix listing of release notes on Releases page ([#7030](https://github.com/networkx/networkx/pull/7030) ). * Fix syntax warning from bad escape sequence ([#7034](https://github.com/networkx/networkx/pull/7034) ). * Fix triangles to avoid using `is` to compare nodes ([#7041](https://github.com/networkx/networkx/pull/7041) ). * Fix error message for `nx.mycielski_graph(0)` ([#7056](https://github.com/networkx/networkx/pull/7056) ). * Disallow negative number of nodes in `complete_multipartite_graph` ([#7057](https://github.com/networkx/networkx/pull/7057) ). * Handle edge cases for greedy\_modularity\_communities ([#6973](https://github.com/networkx/networkx/pull/6973) ). * FIX: Match the doc description while copying over data ([#7092](https://github.com/networkx/networkx/pull/7092) ). * fix: Include singleton/trivial paths in all\_simple\_paths & other functions ([#6694](https://github.com/networkx/networkx/pull/6694) ). * Dinitz correction ([#6968](https://github.com/networkx/networkx/pull/6968) ). * Modify GML test to fix invalid octal character warning ([#7159](https://github.com/networkx/networkx/pull/7159) ). * Fix random\_spanning\_tree() for single node and empty graphs ([#7211](https://github.com/networkx/networkx/pull/7211) ). * PlanarEmbedding.remove\_edge() now updates removed edge’s neighbors ([#6798](https://github.com/networkx/networkx/pull/6798) ). * add seed to graph creation ([#7241](https://github.com/networkx/networkx/pull/7241) ). * add seed to tests of fast\_label\_propatation\_communities ([#7242](https://github.com/networkx/networkx/pull/7242) ). * Fix rich\_club\_coefficient() for single node and empty graphs ([#7212](https://github.com/networkx/networkx/pull/7212) ). * Fix minimum\_spanning\_arborescence regression ([#7280](https://github.com/networkx/networkx/pull/7280) ). * Move arrowstyle input munging after intput validation ([#7293](https://github.com/networkx/networkx/pull/7293) ). * Fix empty GraphML attribute is not parsed ([#7319](https://github.com/networkx/networkx/pull/7319) ). * Add new test result to `test_asadpour_tsp` and change `linprog` method ([#7335](https://github.com/networkx/networkx/pull/7335) ). * Fix custom weight attribute for Mehlhorn ([#6681](https://github.com/networkx/networkx/pull/6681) ). Documentation[#](#documentation "Link to this heading") -------------------------------------------------------- * Update release process ([#7029](https://github.com/networkx/networkx/pull/7029) ). * Update convert\_matrix.py ([#7018](https://github.com/networkx/networkx/pull/7018) ). * fix extendability function name in bipartite.rst ([#7042](https://github.com/networkx/networkx/pull/7042) ). * Minor doc cleanups to remove doc build warnings ([#7048](https://github.com/networkx/networkx/pull/7048) ). * DOC: Add example to generic\_bfs\_edges to demonstrate the `neighbors` param ([#7072](https://github.com/networkx/networkx/pull/7072) ). * Hierarchical clustering layout gallery example ([#7058](https://github.com/networkx/networkx/pull/7058) ). * Fixed an error in the documentation of the katz centrality ([#6294](https://github.com/networkx/networkx/pull/6294) ). * Create 3d\_rotation\_anime.py ([#7025](https://github.com/networkx/networkx/pull/7025) ). * DOC: Add docstrings to filter view functions ([#7086](https://github.com/networkx/networkx/pull/7086) ). * DOC: Add docstrings to Filter mapping views ([#7075](https://github.com/networkx/networkx/pull/7075) ). * DOCS: Fix internal links to other functions in isomorphvf2 ([#6706](https://github.com/networkx/networkx/pull/6706) ). * added note for the triangle inequality case in TSP ([#6995](https://github.com/networkx/networkx/pull/6995) ). * Add note about importance of testing to contributor guide ([#7103](https://github.com/networkx/networkx/pull/7103) ). * Proposal to add centrality overview to mentored projects ([#7104](https://github.com/networkx/networkx/pull/7104) ). * Improve documentation of Component Algorithms ([#5473](https://github.com/networkx/networkx/pull/5473) ). * Add dot io to readwrite ([#5061](https://github.com/networkx/networkx/pull/5061) ). * Add Python versions to release notes ([#7113](https://github.com/networkx/networkx/pull/7113) ). * DOC: Turn on inline plots in graph generators docstrings ([#6401](https://github.com/networkx/networkx/pull/6401) ). * Fix duplicate numbering in contributor guide ([#7116](https://github.com/networkx/networkx/pull/7116) ). * DOC: remove unnecessary ‘or’ in planted\_partition\_graph ([#7115](https://github.com/networkx/networkx/pull/7115) ). * DOC: Link methods in functions to base Graph methods/properties ([#7125](https://github.com/networkx/networkx/pull/7125) ). * Connect docs to doc\_string for total\_spanning\_tree\_weight ([#7098](https://github.com/networkx/networkx/pull/7098) ). * Image (3D RGB data) segmentation by spectral clustering with 3D illustrations ([#7040](https://github.com/networkx/networkx/pull/7040) ). * update triadic\_census documentation for undirected graphs - issue 4386 ([#7141](https://github.com/networkx/networkx/pull/7141) ). * added 3d and animation to plot\_greedy\_coloring.py ([#7090](https://github.com/networkx/networkx/pull/7090) ). * DOC: fix URL econded links and doc references ([#7152](https://github.com/networkx/networkx/pull/7152) ). * DOC: add reference to fast\_label\_propagation\_communities ([#7167](https://github.com/networkx/networkx/pull/7167) ). * updated See also sec of argmap class ([#7163](https://github.com/networkx/networkx/pull/7163) ). * DOC : updated examples in mincost.py ([#7169](https://github.com/networkx/networkx/pull/7169) ). * Document the walk\_type argument default in directed\_laplacian and similar functions ([#7171](https://github.com/networkx/networkx/pull/7171) ). * DOC: Add plots to classic graph generators docs ([#7114](https://github.com/networkx/networkx/pull/7114) ). * Fix a tiny typo in `structuralholes.py::local_constraint` docstring ([#7198](https://github.com/networkx/networkx/pull/7198) ). * Added `subgraph_is_monomorphic` and `subgraph_monomorphisms_iter` in docs ([#7197](https://github.com/networkx/networkx/pull/7197) ). * Fix online docs for `_dispatch` ([#7194](https://github.com/networkx/networkx/pull/7194) ). * DOC : Updated docs for panther\_similarity ([#7175](https://github.com/networkx/networkx/pull/7175) ). * Fix warnings when building docs ([#7195](https://github.com/networkx/networkx/pull/7195) ). * Improve docs for optimal\_edit\_paths ([#7130](https://github.com/networkx/networkx/pull/7130) ). * DOC: build with nx-parallel extra documentation information ([#7220](https://github.com/networkx/networkx/pull/7220) ). * Fixed typo in tensor product documentation (Fixes #7228) ([#7229](https://github.com/networkx/networkx/pull/7229) ). * Add example for cycle detection ([#6560](https://github.com/networkx/networkx/pull/6560) ). * Update general\_k\_edge\_subgraphs docstring ([#7254](https://github.com/networkx/networkx/pull/7254) ). * Update docstring of nonisomorphic\_trees ([#7255](https://github.com/networkx/networkx/pull/7255) ). * adding self loops related docs and tests for functions in `cluster.py` ([#7261](https://github.com/networkx/networkx/pull/7261) ). * Add minimum\_cycle\_basis to cycle\_basis See Also ([#7274](https://github.com/networkx/networkx/pull/7274) ). * Update CONTRIBUTING.rst ([#7270](https://github.com/networkx/networkx/pull/7270) ). * Fix all sphinx warnings during doc build ([#7289](https://github.com/networkx/networkx/pull/7289) ). * Doc infrastructure: replace `nb2plot` with `myst-nb` ([#7237](https://github.com/networkx/networkx/pull/7237) ). * Add explicit targets of missing modules for intersphinx ([#7313](https://github.com/networkx/networkx/pull/7313) ). * DOC: add doc suggestions for arbitrarily large random integers tools ([#7322](https://github.com/networkx/networkx/pull/7322) ). * Try/except intermittently failing basemaps in geospatial examples ([#7324](https://github.com/networkx/networkx/pull/7324) ). * Update docstring example with future-proof pandas assignment ([#7323](https://github.com/networkx/networkx/pull/7323) ). * Remove animation from spectral clustering example to improve performance ([#7328](https://github.com/networkx/networkx/pull/7328) ). * Doc Improvements for Approximations Files ([#7338](https://github.com/networkx/networkx/pull/7338) ). * Update `LCF_graph` docstring ([#7262](https://github.com/networkx/networkx/pull/7262) ). * Option to include initial labels in `weisfeiler_lehman_subgraph_hashes` ([#6601](https://github.com/networkx/networkx/pull/6601) ). * Add eriknw as contributor ([#7343](https://github.com/networkx/networkx/pull/7343) ). * \[DOC, DISPATCH\] : updated and added `backend.py`’s docs ([#7305](https://github.com/networkx/networkx/pull/7305) ). * add \*\*kwargs to traveling\_salesman\_problem ([#7371](https://github.com/networkx/networkx/pull/7371) ). * Move the backend docs and connect the config docs. Both in a single sidebar entry ([#7389](https://github.com/networkx/networkx/pull/7389) ). Maintenance[#](#maintenance "Link to this heading") ---------------------------------------------------- * Drop Python 3.9 support ([#7028](https://github.com/networkx/networkx/pull/7028) ). * fix: Explicitly check for None/False in edge\_attr during import from np ([#6825](https://github.com/networkx/networkx/pull/6825) ). * Add favicon ([#7043](https://github.com/networkx/networkx/pull/7043) ). * Remove unused code resistance\_distance ([#7053](https://github.com/networkx/networkx/pull/7053) ). * Fix names of small graphs ([#7055](https://github.com/networkx/networkx/pull/7055) ). * Improve error messages for misconfigured backend treatment ([#7062](https://github.com/networkx/networkx/pull/7062) ). * MAINT: Fixup union exception message ([#7071](https://github.com/networkx/networkx/pull/7071) ). * MAINT: Minor touchups to tadpole and lollipop graph ([#7049](https://github.com/networkx/networkx/pull/7049) ). * Add `@not_implemented_for("directed")` to `number_connected_components` ([#7074](https://github.com/networkx/networkx/pull/7074) ). * remove unused code ([#7076](https://github.com/networkx/networkx/pull/7076) ). * Minor touchups to the beamsearch module ([#7059](https://github.com/networkx/networkx/pull/7059) ). * Fix annoying split strings on same line ([#7079](https://github.com/networkx/networkx/pull/7079) ). * Update dispatch decorator for `hits` to use `"weight"` edge weight ([#7081](https://github.com/networkx/networkx/pull/7081) ). * Remove nbconvert upper pin (revert #6984) ([#7083](https://github.com/networkx/networkx/pull/7083) ). * Add a step to CI to check for warnings at import time ([#7077](https://github.com/networkx/networkx/pull/7077) ). * Added few tests for /generators/duplication.py and /generators/geomet… ([#6976](https://github.com/networkx/networkx/pull/6976) ). * Test on Python 3.13-dev ([#7096](https://github.com/networkx/networkx/pull/7096) ). * Changed arguments list of GraphMLWriterLxml.dump() ([#6261](https://github.com/networkx/networkx/pull/6261) ). * `write_graphml`: Small fix for object type description on `TypeError` exception ([#7109](https://github.com/networkx/networkx/pull/7109) ). * updated functions in `core.py` ([#7027](https://github.com/networkx/networkx/pull/7027) ). * label check on push and change check name ([#7111](https://github.com/networkx/networkx/pull/7111) ). * DEP : adding `not_implemented_for("multigraph”)` to `k_core`, `k_shell`, `k_crust` and `k_corona` ([#7121](https://github.com/networkx/networkx/pull/7121) ). * Add label check when pull request is edited instead of push ([#7134](https://github.com/networkx/networkx/pull/7134) ). * Add label workflow pull\_request type synchronize and echo message ([#7135](https://github.com/networkx/networkx/pull/7135) ). * adding test coverage for isomorphism when using digraphs ([#6417](https://github.com/networkx/networkx/pull/6417) ). * Remove usage of `__networkx_plugin__` (use `__networkx_backend__` instead) ([#7157](https://github.com/networkx/networkx/pull/7157) ). * DOC: consistent spelling of neighbor and rename vars ([#7162](https://github.com/networkx/networkx/pull/7162) ). * MAINT: use ruff format instead of black ([#7160](https://github.com/networkx/networkx/pull/7160) ). * Ensure warnings related to changes in shortest\_path returns are visible to users ([#7161](https://github.com/networkx/networkx/pull/7161) ). * Sync up behavior of is\_{type} for empty graphs ([#5849](https://github.com/networkx/networkx/pull/5849) ). * Added `NodeNotFound` exceptions to `_apply_prediction` and `simrank`, and ignored isolated nodes in `panther_similarity` ([#7110](https://github.com/networkx/networkx/pull/7110) ). * Fix not\_implemented\_for decorator for is\_regular and related functions ([#7182](https://github.com/networkx/networkx/pull/7182) ). * Fix all\_node\_cuts output for complete graphs ([#6558](https://github.com/networkx/networkx/pull/6558) ). * Remove `"networkx.plugins"` and `"networkx.plugin_info"` entry-points ([#7192](https://github.com/networkx/networkx/pull/7192) ). * Bump actions/setup-python from 4 to 5 ([#7201](https://github.com/networkx/networkx/pull/7201) ). * Update test suite for Pytest v8 ([#7203](https://github.com/networkx/networkx/pull/7203) ). * Undeprecate ` ``nx_pydot`` ` now that pydot is actively maintained again ([#7204](https://github.com/networkx/networkx/pull/7204) ). * Future-proofing and improve tests ([#7209](https://github.com/networkx/networkx/pull/7209) ). * Drop old dependencies per SPEC 0 ([#7217](https://github.com/networkx/networkx/pull/7217) ). * Update pygraphviz ([#7216](https://github.com/networkx/networkx/pull/7216) ). * Refactor geometric\_soft\_configuration\_model tests for performance ([#7210](https://github.com/networkx/networkx/pull/7210) ). * Rename `_dispatch` to `_dispatchable` ([#7193](https://github.com/networkx/networkx/pull/7193) ). * Replace tempfile with tmp\_path fixture in test suite ([#7221](https://github.com/networkx/networkx/pull/7221) ). * updated test\_directed\_edge\_swap #5814 ([#6426](https://github.com/networkx/networkx/pull/6426) ). * Bump copyright year for 2024 ([#7232](https://github.com/networkx/networkx/pull/7232) ). * Improving test coverage for Small.py ([#7260](https://github.com/networkx/networkx/pull/7260) ). * Test for symmetric edge flow betweenness partition ([#7251](https://github.com/networkx/networkx/pull/7251) ). * MAINT : added `seed` to `gnm_random_graph` in `community/tests/test_label_propagation.py` ([#7264](https://github.com/networkx/networkx/pull/7264) ). * Bump scientific-python/upload-nightly-action from 0.2.0 to 0.3.0 ([#7266](https://github.com/networkx/networkx/pull/7266) ). * adding self loops related docs and tests for functions in `cluster.py` ([#7261](https://github.com/networkx/networkx/pull/7261) ). * Improving test coverage for Mycielsky.py ([#7271](https://github.com/networkx/networkx/pull/7271) ). * Use ruff’s docstring formatting ([#7276](https://github.com/networkx/networkx/pull/7276) ). * Add docstring formatting change to blame-ignore-revs ([#7281](https://github.com/networkx/networkx/pull/7281) ). * Improve test coverage for random\_clustered and update function names ([#7273](https://github.com/networkx/networkx/pull/7273) ). * Doc infrastructure: replace `nb2plot` with `myst-nb` ([#7237](https://github.com/networkx/networkx/pull/7237) ). * Temporarily rm geospatial examples to fix CI ([#7299](https://github.com/networkx/networkx/pull/7299) ). * Improve test coverage for bipartite extendability ([#7306](https://github.com/networkx/networkx/pull/7306) ). * CI: Update scientific-python/upload-nightly-action from 0.3.0 to 0.4.0 ([#7309](https://github.com/networkx/networkx/pull/7309) ). * CI: Group dependabot updates ([#7308](https://github.com/networkx/networkx/pull/7308) ). * CI: update upload-nightly-action to 0.5.0 ([#7311](https://github.com/networkx/networkx/pull/7311) ). * renaming backend `func_info` dictionary’s keys ([#7219](https://github.com/networkx/networkx/pull/7219) ). * Add `mutates_input=` and `returns_graph=` to `_dispatchable` ([#7191](https://github.com/networkx/networkx/pull/7191) ). * Avoid creating results with numpy scalars (re: NEP 51) ([#7282](https://github.com/networkx/networkx/pull/7282) ). * Bump changelist from 0.4 to 0.5 ([#7325](https://github.com/networkx/networkx/pull/7325) ). * Improve test coverage for bipartite matrix.py ([#7312](https://github.com/networkx/networkx/pull/7312) ). * Un-dispatch coloring strategies ([#7329](https://github.com/networkx/networkx/pull/7329) ). * Undo change in return type of `single_target_shortest_path_length` ([#7327](https://github.com/networkx/networkx/pull/7327) ). * Remove animation from spectral clustering example to improve performance ([#7328](https://github.com/networkx/networkx/pull/7328) ). * Expire steinertree mehlhorn futurewarning ([#7337](https://github.com/networkx/networkx/pull/7337) ). * Update louvain test modularity comparison to leq ([#7336](https://github.com/networkx/networkx/pull/7336) ). * Add aaronzo as contributor ([#7342](https://github.com/networkx/networkx/pull/7342) ). * Fix #7339. `shortest_path` inconsisitent with warning ([#7341](https://github.com/networkx/networkx/pull/7341) ). * Add `nx.config` dict for configuring dispatching and backends ([#7225](https://github.com/networkx/networkx/pull/7225) ). * Improve test coverage for Steiner Tree & Docs ([#7348](https://github.com/networkx/networkx/pull/7348) ). * added `seed` to `test_richclub_normalized` ([#7355](https://github.com/networkx/networkx/pull/7355) ). * Add tests to link\_prediction.py ([#7357](https://github.com/networkx/networkx/pull/7357) ). * Fix pydot tests when testing backends ([#7356](https://github.com/networkx/networkx/pull/7356) ). * Future proof xml parsing in graphml ([#7360](https://github.com/networkx/networkx/pull/7360) ). * make doc\_string examples order-independent by removing np.set\_printoptions ([#7361](https://github.com/networkx/networkx/pull/7361) ). * Close figures on test cleanup ([#7373](https://github.com/networkx/networkx/pull/7373) ). * More numpy scalars cleanup for numpy 2.0 ([#7374](https://github.com/networkx/networkx/pull/7374) ). * Update numpydoc ([#7364](https://github.com/networkx/networkx/pull/7364) ). * Fix pygraphviz tests causing segmentation faults in backend test ([#7380](https://github.com/networkx/networkx/pull/7380) ). * Add dispatching to broadcasting.py ([#7386](https://github.com/networkx/networkx/pull/7386) ). * Update test suite to handle when scipy is not installed ([#7388](https://github.com/networkx/networkx/pull/7388) ). * Rm deprecated np.row\_stack in favor of vstack ([#7390](https://github.com/networkx/networkx/pull/7390) ). * Fix exception for `del config[key]` ([#7391](https://github.com/networkx/networkx/pull/7391) ). * Bump the GH actions with 3 updates ([#7310](https://github.com/networkx/networkx/pull/7310) ). Contributors[#](#contributors "Link to this heading") ------------------------------------------------------ 54 authors added to this release (alphabetically): * [@BucketHeadP65](https://github.com/BucketHeadP65) * [@dependabot\[bot\]](https://github.com/apps/dependabot) * [@nelsonaloysio](https://github.com/nelsonaloysio) * [@YVWX](https://github.com/YVWX) * Aaron Z. ([@aaronzo](https://github.com/aaronzo) ) * Aditi Juneja ([@Schefflera-Arboricola](https://github.com/Schefflera-Arboricola) ) * AKSHAYA MADHURI ([@akshayamadhuri](https://github.com/akshayamadhuri) ) * Alex Markham ([@Alex-Markham](https://github.com/Alex-Markham) ) * Anders Rydbirk ([@anders-rydbirk](https://github.com/anders-rydbirk) ) * Andrew Knyazev ([@lobpcg](https://github.com/lobpcg) ) * Ayooluwa ([@Ay-slim](https://github.com/Ay-slim) ) * Baldo ([@BrunoBaldissera](https://github.com/BrunoBaldissera) ) * Benjamin Edwards ([@bjedwards](https://github.com/bjedwards) ) * Chiranjeevi Karthik Kuruganti ([@karthikchiru12](https://github.com/karthikchiru12) ) * Chris Pryer ([@cnpryer](https://github.com/cnpryer) ) * d.grigonis ([@dgrigonis](https://github.com/dgrigonis) ) * Dan Schult ([@dschult](https://github.com/dschult) ) * Daniel V. Egdal ([@DanielEgdal](https://github.com/DanielEgdal) ) * Dilara Tekinoglu ([@dtekinoglu](https://github.com/dtekinoglu) ) * Dishie Vinchhi ([@Dishie2498](https://github.com/Dishie2498) ) * Erik Welch ([@eriknw](https://github.com/eriknw) ) * Frédéric Crozatier ([@fcrozatier](https://github.com/fcrozatier) ) * Henrik Finsberg ([@finsberg](https://github.com/finsberg) ) * Jangwon Yie ([@jangwon-yie](https://github.com/jangwon-yie) ) * Jaron Lee ([@jaron-lee](https://github.com/jaron-lee) ) * Jarrod Millman ([@jarrodmillman](https://github.com/jarrodmillman) ) * Jon Crall ([@Erotemic](https://github.com/Erotemic) ) * Jonas Otto ([@ottojo](https://github.com/ottojo) ) * Jordan Matelsky ([@j6k4m8](https://github.com/j6k4m8) ) * Koen van den Berk ([@kalkoen](https://github.com/kalkoen) ) * Luigi Sciarretta ([@LuigiSciar](https://github.com/LuigiSciar) ) * Luigi Sciarretta ([@LuigiSciarretta](https://github.com/LuigiSciarretta) ) * Matt Schwennesen ([@mjschwenne](https://github.com/mjschwenne) ) * Matthew Feickert ([@matthewfeickert](https://github.com/matthewfeickert) ) * Matthieu Gouel ([@matthieugouel](https://github.com/matthieugouel) ) * Mauricio Souza de Alencar ([@mdealencar](https://github.com/mdealencar) ) * Maximilian Seeliger ([@max-seeli](https://github.com/max-seeli) ) * Mridul Seth ([@MridulS](https://github.com/MridulS) ) * Navya Agarwal ([@navyagarwal](https://github.com/navyagarwal) ) * Neil Botelho ([@NeilBotelho](https://github.com/NeilBotelho) ) * Nihal John George ([@nihalgeorge01](https://github.com/nihalgeorge01) ) * Paolo Lammens ([@plammens](https://github.com/plammens) ) * Patrick Nicodemus ([@patrick-nicodemus](https://github.com/patrick-nicodemus) ) * Paula Pérez Bianchi ([@paulitapb](https://github.com/paulitapb) ) * Purvi Chaurasia ([@PurviChaurasia](https://github.com/PurviChaurasia) ) * Robert ([@ImHereForTheCookies](https://github.com/ImHereForTheCookies) ) * Robert Jankowski ([@robertjankowski](https://github.com/robertjankowski) ) * Ross Barnowski ([@rossbar](https://github.com/rossbar) ) * Sadra Barikbin ([@sadra-barikbin](https://github.com/sadra-barikbin) ) * Salim BELHADDAD ([@salym](https://github.com/salym) ) * Till Hoffmann ([@tillahoffmann](https://github.com/tillahoffmann) ) * Vanshika Mishra ([@vanshika230](https://github.com/vanshika230) ) * William Black ([@smokestacklightnin](https://github.com/smokestacklightnin) ) * William Zijie Zhang ([@Transurgeon](https://github.com/Transurgeon) ) 29 reviewers added to this release (alphabetically): * [@YVWX](https://github.com/YVWX) * Aaron Z. ([@aaronzo](https://github.com/aaronzo) ) * Aditi Juneja ([@Schefflera-Arboricola](https://github.com/Schefflera-Arboricola) ) * AKSHAYA MADHURI ([@akshayamadhuri](https://github.com/akshayamadhuri) ) * Andrew Knyazev ([@lobpcg](https://github.com/lobpcg) ) * Ayooluwa ([@Ay-slim](https://github.com/Ay-slim) ) * Chiranjeevi Karthik Kuruganti ([@karthikchiru12](https://github.com/karthikchiru12) ) * Chris Pryer ([@cnpryer](https://github.com/cnpryer) ) * d.grigonis ([@dgrigonis](https://github.com/dgrigonis) ) * Dan Schult ([@dschult](https://github.com/dschult) ) * Erik Welch ([@eriknw](https://github.com/eriknw) ) * Frédéric Crozatier ([@fcrozatier](https://github.com/fcrozatier) ) * Henrik Finsberg ([@finsberg](https://github.com/finsberg) ) * Jarrod Millman ([@jarrodmillman](https://github.com/jarrodmillman) ) * Kyle Sunden ([@ksunden](https://github.com/ksunden) ) * Matt Schwennesen ([@mjschwenne](https://github.com/mjschwenne) ) * Mauricio Souza de Alencar ([@mdealencar](https://github.com/mdealencar) ) * Maximilian Seeliger ([@max-seeli](https://github.com/max-seeli) ) * Mridul Seth ([@MridulS](https://github.com/MridulS) ) * Nihal John George ([@nihalgeorge01](https://github.com/nihalgeorge01) ) * Paolo Lammens ([@plammens](https://github.com/plammens) ) * Paula Pérez Bianchi ([@paulitapb](https://github.com/paulitapb) ) * Rick Ratzel ([@rlratzel](https://github.com/rlratzel) ) * Robert Jankowski ([@robertjankowski](https://github.com/robertjankowski) ) * Ross Barnowski ([@rossbar](https://github.com/rossbar) ) * Stefan van der Walt ([@stefanv](https://github.com/stefanv) ) * Vanshika Mishra ([@vanshika230](https://github.com/vanshika230) ) * William Black ([@smokestacklightnin](https://github.com/smokestacklightnin) ) * William Zijie Zhang ([@Transurgeon](https://github.com/Transurgeon) ) \_These lists are automatically generated, and may not be complete or may contain duplicates.\_ On this page --- # Euler’s Algorithm — NetworkX Notebooks [Skip to main content](#main-content) Back to top Ctrl+K [![NetworkX Notebooks - Home](../../../_static/networkx_banner.svg) ![NetworkX Notebooks - Home](../../../_static/networkx_banner.svg)](../../../index.html) * [GitHub](https://github.com/networkx/nx-guides/ "GitHub") Search Ctrl+K * [![Binder logo](../../../_static/images/logo_binder.svg)Binder](https://mybinder.org/v2/gh/networkx/nx-guides/main?urlpath=tree/site/content/algorithms/euler/euler.md "Launch on Binder") * [Repository](https://github.com/networkx/nx-guides "Source repository") * [Suggest edit](https://github.com/networkx/nx-guides/edit/main/site/content/algorithms/euler/euler.md "Suggest edit") * [Open issue](https://github.com/networkx/nx-guides/issues/new?title=Issue%20on%20page%20%2Fcontent/algorithms/euler/euler.html&body=Your%20issue%20content%20here. "Open an issue") * [.ipynb](../../../_sources/content/algorithms/euler/euler.ipynb "Download notebook file") * [.md](../../../_sources/content/algorithms/euler/euler.md "Download source file") * .pdf Euler’s Algorithm ================= Contents -------- Euler’s Algorithm[#](#euler-s-algorithm "Link to this heading") ================================================================ In this tutorial, we will explore Euler’s algorithm and its implementation in NetworkX under [`networkx/algorithms/euler.py`](https://github.com/networkx/networkx/blob/main/networkx/algorithms/euler.py) . Import package[#](#import-package "Link to this heading") ---------------------------------------------------------- import networkx as nx Seven Bridges of Königsberg[#](#seven-bridges-of-konigsberg "Link to this heading") ------------------------------------------------------------------------------------ What you are seeing below is the beautiful old town of Königsberg which is famous for its seven bridges. Each of these bridges either connect two large islands — Kneiphof and Lomse — or two mainland portions of the city. ![image:map](../../../_images/map.png) What gave the town its fame is a question that was asked to mathematician Leonhard Euler almost 300 years ago [\[1\]](#id3) : > _**Can you take a walk through Königsberg visiting each mass by crossing each bridge once and only once?**_ Euler’s negative resolution to this question laid the foundations of graph theory. Before diving into Euler’s solution, let’s reformulate the problem. ### Reformulating the Problem in Abstract Terms[#](#reformulating-the-problem-in-abstract-terms "Link to this heading") In order to have a clear look, we should first simplify the map a little. ![image:part1](../../../_images/part1.png) Euler observed that the choice of route inside each land mass is irrelevant. The only thing that matters is the sequence of bridges to be crossed. This observation allows us to abstract the problem even more. In the graph below, blue vertices represent the land masses and edges represent the bridges that connect them. \# Create graph G \= nx.DiGraph() G.add\_edge("A", "B", label\="a") G.add\_edge("B", "A", label\="b") G.add\_edge("A", "C", label\="c") G.add\_edge("C", "A", label\="d") G.add\_edge("A", "D", label\="e") G.add\_edge("B", "D", label\="f") G.add\_edge("C", "D", label\="g") positions \= {"A": (0, 0), "B": (1, \-2), "C": (1, 2), "D": (2, 0)} \# Visualize graph nx.draw\_networkx\_nodes(G, pos\=positions, node\_size\=500) nx.draw\_networkx\_edges( G, pos\=positions, edgelist\=\[("A", "D"), ("B", "D"), ("C", "D")\], arrowstyle\="-" ) nx.draw\_networkx\_edges( G, pos\=positions, edgelist\=\[("A", "B"), ("B", "A"), ("C", "A"), ("A", "C")\], arrowstyle\="-", connectionstyle\="arc3,rad=0.2", ); ![../../../_images/f8bd22c8838fd55a6cb1e9dee573e8ddc59c4db1ee5fdb026ad268c12ef7f264.png](../../../_images/f8bd22c8838fd55a6cb1e9dee573e8ddc59c4db1ee5fdb026ad268c12ef7f264.png) Based on this abstraction, we can paraphrase the problem as follows: > _**Can you draw the above graph without lifting your pen or crossing on a line more than once?**_ If you can, it means there is an _**Euler Path**_ in the graph. If this path starts and ends at the same blue circle, it is called an _**Euler Circuit**_. Note that every Euler Circuit is also an Euler Path. ### Euler’s Method[#](#euler-s-method "Link to this heading") Euler [\[2\]](#id4) denoted land masses of the town by capital letters \\(A\\), \\(B\\), \\(C\\) and \\(D\\) and bridges by lowercase \\(a\\), \\(b\\), \\(c\\), \\(d\\), \\(e\\), \\(f\\) and \\(g\\). Let’s draw the graph based on this node and edge labels. \# Design and draw graph edge\_labels \= nx.get\_edge\_attributes(G, "label") nx.draw\_networkx\_nodes(G, pos\=positions, node\_size\=500) nx.draw\_networkx\_labels(G, pos\=positions, font\_color\="w") nx.draw\_networkx\_edges( G, pos\=positions, edgelist\=\[("A", "D"), ("B", "D"), ("C", "D")\], arrowstyle\="-" ) nx.draw\_networkx\_edges( G, pos\=positions, edgelist\=\[("A", "B"), ("B", "A"), ("C", "A"), ("A", "C")\], arrowstyle\="-", connectionstyle\="arc3,rad=0.2", ) nx.draw\_networkx\_edge\_labels(G, pos\=positions, edge\_labels\=edge\_labels, label\_pos\=0.2); ![../../../_images/0dd9b481e43f2d5099f596b66b47bee7890a497b75468d4f17cf6c3b448c7057.png](../../../_images/0dd9b481e43f2d5099f596b66b47bee7890a497b75468d4f17cf6c3b448c7057.png) He described his logic as follows: * If we cross bridge \\(a\\), we walk from \\(A\\) to \\(B\\). In this case, our travel route is denoted as \\(AB\\). * If we cross first \\(a\\) and then \\(f\\), our route will be \\(ABD\\). * So, sequential use of \\(n\\) bridges is denoted with \\(n+1\\) capital letters. * Since we need to cross each of 7 bridges, our route should consist of a sequence of \\(A\\), \\(B\\), \\(C\\) and \\(D\\) of length 8. He also stated the fact that number of appearances of each land mass in the route depend on the number of bridges it has. * \\(A\\) has 5 bridges. All these 5 bridges should appear in our Euler Path exactly once. Then, \\(A\\) should appear in our route for 3 times. * \\(B\\) has 3 bridges. It should appear in the route for 2 times. * \\(C\\) has 3 bridges. It should appear in the route for 2 times. * \\(D\\) has 3 bridges. It should appear in the route for 2 times. * Then, the total length of the route should be 3 + 2 + 2 + 2 = 9. It is obvious that we cannot satisfy both of these conditions at the same time. Therefore, Euler concluded that there is no solution to Seven Bridges of Königsberg problem (I.e. Königsberg does not have an Euler Path). ### Generalizing Euler’s Solution[#](#generalizing-euler-s-solution "Link to this heading") Euler generalized the method he applied for Königsberg problem as follows: > _**A graph has an Euler Path if and only if the number of vertices with odd degree is either zero or two.**_ * If there are two vertices with odd degree, then they are the starting and ending vertices. * If there are no vertices with odd degree, any vertex can be starting or ending vertex and the graph has also an Euler Circuit. Euler’s Algorithm in NetworkX[#](#euler-s-algorithm-in-networkx "Link to this heading") ---------------------------------------------------------------------------------------- NetworkX implements several methods using the Euler’s algorithm. These are: * **is\_eulerian** : Whether the graph has an Eulerian circuit * **eulerian\_circuit** : Sequence of edges of an Eulerian circuit in the graph. * **eulerize** : Transforms a graph into an Eulerian graph * **is\_semieulerian** : Whether the graph has an Eulerian path but not an Eulerian circuit. * **has\_eulerian\_path**: Whether the graph has an Eulerian path. * **eulerian\_path** : Sequence of edges of in Eulerian path in the graph. In this part, we will briefly explain the NetworkX implementation of Euler’s algorithm by explaining some of these methods. **Note**: NetworkX implementation does not allow graphs with isolated nodes to have Eulerian Path and/or Eulerian Circuit. Thus, an Eulerian Path or Eulerian Circuit must visit not only all edges, but also all vertices of the graph. ### 1\. Eulerian Circuit Implementation[#](#eulerian-circuit-implementation "Link to this heading") Implementation of the `is_eulerian` method is quite simple. In order to have an Euler circuit (i.e. to be Eulerian): * A directed graph must be strongly connected and every vertex of it must have equal in degree and out degree. * An undirected graph must be connected, and it must have no vertices of odd degree. Here is an example: T \= nx.Graph(\[(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (2, 3), (2, 4)\]) nx.draw( T, with\_labels\=True, node\_size\=1000, font\_color\="White", node\_color\="darkorange" ) ![../../../_images/8e030d7c72b3c900530422f68b9fd36b8166784ecc3279b7e1912686919396e9.png](../../../_images/8e030d7c72b3c900530422f68b9fd36b8166784ecc3279b7e1912686919396e9.png) def is\_eulerian(G): if G.is\_directed(): return all( G.in\_degree(n) \== G.out\_degree(n) for n in G ) and nx.is\_strongly\_connected(G) else: return all(d % 2 \== 0 for v, d in G.degree()) and nx.is\_connected(G) is\_eulerian(T) True NetworkX has also implemented the `eulerian_circuit` method to determine sequence of edges that consist of a Euler Circuit. The method uses a stack data structure to keep vertices, it starts with the source vertex and pushes into stack. At each following iteration, it pops a vertex from the stack, chooses a neighbor of it, pushes the chosen vertex to the stack and removes the chosen edge from the graph. circuit \= \[\] if G.is\_directed(): degree \= G.out\_degree edges \= G.out\_edges else: degree \= G.degree edges \= G.edges vertex\_stack \= \[0\] last\_vertex \= None while vertex\_stack: current\_vertex \= vertex\_stack\[\-1\] circuit.append(current\_vertex) if G.degree(current\_vertex) \== 0: if last\_vertex is not None: break last\_vertex \= current\_vertex vertex\_stack.pop() else: \_, next\_vertex \= next(iter(G.edges(current\_vertex))) vertex\_stack.append(next\_vertex) G.remove\_edge(current\_vertex, next\_vertex) ### 2\. Eulerian Path Implementation[#](#eulerian-path-implementation "Link to this heading") Networkx implementation of `has_eulerian_path` first checks if the graph `is_eulerian` or not. Remember that if a graph is Eulerian (i.e. has Euler Circuit), then it also has Eulerian Path. def has\_eulerian\_path(G, source\=None): if nx.is\_eulerian(G): return True If an undirected graph is not Eulerian, it can still be `semi_eulerian` meaning that it might have an Eulerian Path with different starting and ending vertices. As explained above, this is possible if and only if * there are exactly two vertices of odd degree, and * all of its vertices belong to a single connected component. If source vertex is given by the user, it must have an odd degree. Otherwise, there cannot be an Eulerian Path starting from the given source. if G.is\_directed() \== False: if source is not None and G.degree\[source\] % 2 != 1: return False return(sum(d % 2 \== 1 for \_, d in G.degree()) \== 2 and nx.is\_connected(G)) For a directed graph to has an Eulerian Path, it must have * at most one vertex has out\_degree - in\_degree = 1, * at most one vertex has in\_degree - out\_degree = 1, * every other vertex has equal in\_degree and out\_degree, and * all of its vertices belong to a single connected component of the underlying undirected graph _(I.e. Should be weakly connected)_. if G.is\_directed(): ins \= G.in\_degree outs \= G.out\_degree if source is not None and outs\[source\] \- ins\[source\] != 1: return False unbalanced\_ins \= 0 unbalanced\_outs \= 0 for v in G: if ins\[v\] \- outs\[v\] \== 1: unbalanced\_ins += 1 elif outs\[v\] \- ins\[v\] \== 1: unbalanced\_outs += 1 elif ins\[v\] != outs\[v\]: return False return ( unbalanced\_ins <= 1 and unbalanced\_outs <= 1 and nx.is\_weakly\_connected(G) ) Using already implemented methods, `is_semieulerian` simply checks if the input graph does not have an Eulerian circuit but an Eulerian path with a one line of code. def is\_semieulerian(G): return has\_eulerian\_path(G) and not is\_eulerian(G) ### 3\. Examples[#](#examples "Link to this heading") Let’s call the methods above on the Seven Bridges problem. For the reasons explained above, we expect our graph to have neither an Eulerian Circuit nor an Eulerian Path. nx.is\_eulerian(G) False nx.has\_eulerian\_path(G) False We can conclude this section with another example. Do you expect a wheel graph to have an Eulerian Path? W \= nx.wheel\_graph(6) nx.draw(W, with\_labels\=True, node\_size\=1000, font\_color\="White", node\_color\="green") ![../../../_images/dd6ef396f3e0a81edd3e69a2be5057ac073c1b5d39a8278bf0709e933ae28829.png](../../../_images/dd6ef396f3e0a81edd3e69a2be5057ac073c1b5d39a8278bf0709e933ae28829.png) The answer is No! All nodes except for the one in the center have exactly 3 edges in the wheel graph. Thus, it cannot have an Eulerian Path. nx.has\_eulerian\_path(W) False Euler is everywhere![#](#euler-is-everywhere "Link to this heading") --------------------------------------------------------------------- Euler’s algorithm is essential for anyone or anything that uses paths. Some examples of its real applications: * To solve many complex problems, like the Konigsberg Seven Bridges Problem explained above. * Mail carriers can use Eulerian Paths to have a route where they don’t have to retrace their previous steps. * Useful for painters, garbage collections, airplane pilots, GPS developers (_e.g. Google Maps developers_). References[#](#references "Link to this heading") -------------------------------------------------- Contents --- # NXEPs — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NXEPs[#](#nxeps "Link to this heading") ======================================== NetworkX Enhancement Proposals (NXEPs) document major changes or proposals. * [NXEP 0 — Purpose and Process](nxep-0000.html) * [NXEP 1 — Governance and Decision Making](nxep-0001.html) * [NXEP 2 — API design of view slices](nxep-0002.html) * [NXEP 3 — Graph Builders](nxep-0003.html) * [NXEP 4 — Default random interface](nxep-0004.html) --- # NetworkX 3.2.1 — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NetworkX 3.2.1[#](#networkx-3-2-1 "Link to this heading") ========================================================== Release date: 28 October 2023 Supports Python 3.9, 3.10, 3.11, and 3.12. NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. For more information, please visit our [website](https://networkx.org/) and our [gallery of examples](../auto_examples/index.html#examples-gallery) . Please send comments and questions to the [networkx-discuss mailing list](http://groups.google.com/group/networkx-discuss) . API Changes[#](#api-changes "Link to this heading") ---------------------------------------------------- * Disallow negative number of nodes in `complete_multipartite_graph` ([#7057](https://github.com/networkx/networkx/pull/7057) ). Enhancements[#](#enhancements "Link to this heading") ------------------------------------------------------ * Add Tadpole graph ([#6999](https://github.com/networkx/networkx/pull/6999) ). Bug Fixes[#](#bug-fixes "Link to this heading") ------------------------------------------------ * Fix listing of release notes on Releases page ([#7030](https://github.com/networkx/networkx/pull/7030) ). * Fix syntax warning from bad escape sequence ([#7034](https://github.com/networkx/networkx/pull/7034) ). * Fix triangles to avoid using `is` to compare nodes ([#7041](https://github.com/networkx/networkx/pull/7041) ). * Fix error message for `nx.mycielski_graph(0)` ([#7056](https://github.com/networkx/networkx/pull/7056) ). * Disallow negative number of nodes in `complete_multipartite_graph` ([#7057](https://github.com/networkx/networkx/pull/7057) ). Documentation[#](#documentation "Link to this heading") -------------------------------------------------------- * Update release process ([#7029](https://github.com/networkx/networkx/pull/7029) ). * fix extendability function name in bipartite.rst ([#7042](https://github.com/networkx/networkx/pull/7042) ). * Minor doc cleanups to remove doc build warnings ([#7048](https://github.com/networkx/networkx/pull/7048) ). Maintenance[#](#maintenance "Link to this heading") ---------------------------------------------------- * fix: Explicitly check for None/False in edge\_attr during import from np ([#6825](https://github.com/networkx/networkx/pull/6825) ). * Add favicon ([#7043](https://github.com/networkx/networkx/pull/7043) ). * Remove unused code resistance\_distance ([#7053](https://github.com/networkx/networkx/pull/7053) ). * Fix names of small graphs ([#7055](https://github.com/networkx/networkx/pull/7055) ). * Improve error messages for misconfigured backend treatment ([#7062](https://github.com/networkx/networkx/pull/7062) ). Other[#](#other "Link to this heading") ---------------------------------------- * Update convert\_matrix.py ([#7018](https://github.com/networkx/networkx/pull/7018) ). Contributors[#](#contributors "Link to this heading") ------------------------------------------------------ 8 authors added to this release (alphabetically): * [@peijenburg](https://github.com/peijenburg) * AKSHAYA MADHURI ([@akshayamadhuri](https://github.com/akshayamadhuri) ) * Dan Schult ([@dschult](https://github.com/dschult) ) * Erik Welch ([@eriknw](https://github.com/eriknw) ) * Jarrod Millman ([@jarrodmillman](https://github.com/jarrodmillman) ) * Jonas Otto ([@ottojo](https://github.com/ottojo) ) * Jordan Matelsky ([@j6k4m8](https://github.com/j6k4m8) ) * Ross Barnowski ([@rossbar](https://github.com/rossbar) ) 6 reviewers added to this release (alphabetically): * [@peijenburg](https://github.com/peijenburg) * Dan Schult ([@dschult](https://github.com/dschult) ) * Jarrod Millman ([@jarrodmillman](https://github.com/jarrodmillman) ) * Mridul Seth ([@MridulS](https://github.com/MridulS) ) * Ross Barnowski ([@rossbar](https://github.com/rossbar) ) * Stefan van der Walt ([@stefanv](https://github.com/stefanv) ) \_These lists are automatically generated, and may not be complete or may contain duplicates.\_ On this page --- # Isomorphism - How to find if two graphs are similar? — NetworkX Notebooks [Skip to main content](#main-content) Back to top Ctrl+K [![NetworkX Notebooks - Home](../../../_static/networkx_banner.svg) ![NetworkX Notebooks - Home](../../../_static/networkx_banner.svg)](../../../index.html) * [GitHub](https://github.com/networkx/nx-guides/ "GitHub") Search Ctrl+K * [![Binder logo](../../../_static/images/logo_binder.svg)Binder](https://mybinder.org/v2/gh/networkx/nx-guides/main?urlpath=tree/site/content/algorithms/isomorphism/isomorphism.md "Launch on Binder") * [Repository](https://github.com/networkx/nx-guides "Source repository") * [Suggest edit](https://github.com/networkx/nx-guides/edit/main/site/content/algorithms/isomorphism/isomorphism.md "Suggest edit") * [Open issue](https://github.com/networkx/nx-guides/issues/new?title=Issue%20on%20page%20%2Fcontent/algorithms/isomorphism/isomorphism.html&body=Your%20issue%20content%20here. "Open an issue") * [.ipynb](../../../_sources/content/algorithms/isomorphism/isomorphism.ipynb "Download notebook file") * [.md](../../../_sources/content/algorithms/isomorphism/isomorphism.md "Download source file") * .pdf Isomorphism - How to find if two graphs are similar? ==================================================== Contents -------- Isomorphism - How to find if two graphs are similar?[#](#isomorphism-how-to-find-if-two-graphs-are-similar "Link to this heading") =================================================================================================================================== import networkx as nx import matplotlib.pyplot as plt What is isomorphism? Why is it interesting?[#](#what-is-isomorphism-why-is-it-interesting "Link to this heading") ------------------------------------------------------------------------------------------------------------------ As unlabeled graphs can have multiple spatial representations, two graphs are isomorphic if they have the same number of edges, vertices, and same edges connectivity. Let’s see an example of two isomorphic graphs, plt.subplot(221) G \= nx.cubical\_graph() nx.draw\_spectral(G, with\_labels\=True, node\_color\="c") plt.title("G", fontweight\="bold") H \= nx.cubical\_graph() plt.subplot(222) nx.draw\_circular(H, with\_labels\=True, node\_color\="yellow") plt.title("H", fontweight\="bold") plt.show() ![../../../_images/fe8f477d0436d9b34467bbfe8bf6f324682c3e974eed041a0b819b6c844f8e79.png](../../../_images/fe8f477d0436d9b34467bbfe8bf6f324682c3e974eed041a0b819b6c844f8e79.png) The spatial representations of these two graphs are very different yet they are the same graphs! ### Formal definition[#](#formal-definition "Link to this heading") G and H are isomorphic if we can establish a bijection between the vertex sets of G and H. \\\[ {\\displaystyle f\\colon N(G)\\to N(H)} \\\] such as if \\(v\\) and \\( w \\) are adjacent in G \\(\\iff\\) \\(f(v)\\) and \\(f(w)\\) are adjacent in H To formally prove that 2 graphs are isomorphic we need to find the bijection between the vertex set. For the previous example that would be: \\\[f(i) = i+1 \\hspace{0.5cm} \\forall i \\in \[0, 7\]\\\] For small examples, isomorphism may seem easy. But it isn’t a simple problem. For two graphs G and H of n nodes, there are n! possible bijection functions. Checking every combination is not a feasible option for bigger graphs. In fact, isomorphism is part of the problems known as NP. This means that we don’t know any algorithm that runs in polynomial time. ### Applications[#](#applications "Link to this heading") There are a lot of applications of the graph isomorphism problem. * Image recognition: Images can be translated to graphs and by finding (sub)isomorphisms we can compare if two images are similar. * Verification of equivalence of different representations of the design of an electronic circuit and communication networks. * Identification of chemical compounds and proteins. * Algorithms for fingerprint, facial and retina matching. * Clustering Algorithms on social networks. Isomorphism Algorithms[#](#isomorphism-algorithms "Link to this heading") -------------------------------------------------------------------------- **Naive Approach** There are some initial properties that we can check to decide whether it’s possible to have an isomorphism * G and H must have the same number of nodes and edges * The degree sequence for G and H must be the same These are necessary conditions but don’t guarantee that two graphs are isomorphic. Let’s see a small example: plt.subplot(221) G \= nx.cycle\_graph(6) nx.draw\_circular(G) plt.title("G", fontweight\="bold") plt.subplot(222) H \= nx.union(nx.cycle\_graph(3), nx.cycle\_graph(3), rename\=("s", "d")) nx.draw\_circular(H, node\_color\="r") plt.title("H", fontweight\="bold") plt.show() ![../../../_images/9b0a045264b1bda59bb194d3f8efca434043dfb0edff4ebe1750dadc13277a2f.png](../../../_images/9b0a045264b1bda59bb194d3f8efca434043dfb0edff4ebe1750dadc13277a2f.png) We can use the function `nx.faster_could_be_isomorphic()` that returns True if G and H have the same degree secuence. nx.faster\_could\_be\_isomorphic(G, H) True These graphs are clearly not isomorphic but they have the same degree secuence. Another property we can check for is: * The same number of cycles of a particular length, for example, triangles. We can use the function `nx.fast_could_be_isomorphic()` to check if the graphs have the same degree and triangle sequence. The triangle sequence contains the number of triangles each node is part of. nx.fast\_could\_be\_isomorphic(G, H) False This new property allows us to detect that the graphs from the previous example were not isomorphic. We can go one step further and check: * The same number of maximal cliques. We can use the function `nx.could_be_isomorphic()` to check if the graphs have the same degree, triangle, and clique sequence. The clique sequence contains for each node the number of the maximal clique involving that node. nx.could\_be\_isomorphic(G, H) False Again we can detect that G and H are not isomorphic. But these conditions are not enough to say that two graphs are isomorphic. Let’s look at the following example: plt.subplot(221) G \= nx.path\_graph(5) G.add\_edge(2, 5) nx.draw\_circular(G, with\_labels\=True, node\_color\="g") plt.title("G", fontweight\="bold") plt.subplot(222) H \= nx.path\_graph(5) H.add\_edge(3, 5) nx.draw\_circular(H, with\_labels\=True, node\_color\="c") plt.title("H", fontweight\="bold") plt.show() ![../../../_images/56bba2c8e26c0326bcddb4eac437dd2257b68cd1239d1917be46c07f71c1d8f3.png](../../../_images/56bba2c8e26c0326bcddb4eac437dd2257b68cd1239d1917be46c07f71c1d8f3.png) nx.could\_be\_isomorphic(G, H) True These graphs meet all the necessary conditions but they’re not isomorphic. Some classes of graphs with solution in polynomial time[#](#some-classes-of-graphs-with-solution-in-polynomial-time "Link to this heading") -------------------------------------------------------------------------------------------------------------------------------------------- * Trees * Planar graphs(In fact, planar graph isomorphism is O(log(n))) * Interval graphs * Permutation graphs * Circulant graphs * Bounded-parameter graphs * Graphs of bounded treewidth * Graphs of bounded genus * Graphs of bounded degree * Graphs with bounded eigenvalue multiplicity * k-Contractible graphs (a generalization of bounded degree and bounded genus) Let’s see an example, we can use the function _tree\_isomorphism()_ from the isomorphism module to check if two trees are isomorphic in \\(O(n\*log(n))\\). This function uses a D&C approach to match the trees once it has found the root of each tree and returns a list with the node matching. So let’s use it to check that a 2-ary tree of \\(2^4 - 1\\) nodes is a balanced binary tree of height 3. t1 \= nx.balanced\_tree(2, 3) t2 \= nx.full\_rary\_tree(2, 15) from networkx.algorithms import isomorphism as iso print("Node matching") iso.tree\_isomorphism(t1, t2) Node matching \[(0, 0),\ (1, 1),\ (3, 3),\ (7, 7),\ (8, 8),\ (4, 4),\ (9, 9),\ (10, 10),\ (2, 2),\ (5, 5),\ (11, 11),\ (12, 12),\ (6, 6),\ (13, 13),\ (14, 14)\] Advanced Algorithms[#](#advanced-algorithms "Link to this heading") -------------------------------------------------------------------- ### VF2[#](#vf2 "Link to this heading") This algorithm is used to solve graph isomorphism and sub-graph isomorphism as well. VF2 is a recursive algorithm where in each step we extend the current matching function to cover more nodes of both graphs until there are no more nodes to match. This is not a brute-force approach because there are some feasibility rules to avoid exploring the whole recursion tree. Formally, We have a function \\( M: s \\rightarrow N(G) \\times N(H) \\). \\(M\\) is a matching function between the subsets of nodes from \\(G\\) and \\(H\\) at the current state \\(s\\). We start with an initial state \\(s\_0\\) with \\(M(s\_0) = \\emptyset\\). In each step we consider a set of nodes to expand the current state \\(s\\) to the following state \\(s'\\). In this new state \\(M(s') = M(s) \\cup {(g, h)} , g\\in N(G), h\\in N(H)\\). The consistency condition is that the partial graphs \\(G\\) and \\(H\\) associated with \\(M(s)\\) are isomorphic. There are two types of feasibility checks: * syntactic (graph structure): consist of checking the consistency condition and also the k-look-ahead rules, for checking in advance if a consistent state \\(s\\) has no consistent successors after k steps. * semantic(attributes). Pseudocode: **Match(s):** Input: Intermediate state Output: The mapping between the 2 graphs IF M(s) covers all nodes of H THEN: RETURN M(s) ELSE: Compute P = {(g, h)...} the set of candidates for inclusion in M(s). FOR each p in P: IF the feasibility rules succeed for the inclusion of p in M(s) THEN: Compute the state of s' MATCH(s') ENDIF ENDFOR Restore data structures ENDIF Let’s use VF2 to check that the graphs from the previous example: G \= nx.path\_graph(5) G.add\_edge(2, 5) H \= nx.path\_graph(5) H.add\_edge(3, 5) nx.is\_isomorphic(G, H) False **Time Complexity** * Best Case \\(\\in \\theta(n²)\\) if only \\(n\\) states are explored, for example, if each node is explored once. * Worst Case \\(\\in \\theta(n!n)\\) if all the possible matchings have to be completely explored. State of the art[#](#state-of-the-art "Link to this heading") -------------------------------------------------------------- * VF2++ and VF2 Plus. They include some optimizations over the algorithm VF2. * There are some new algorithms: QuickSI, GraphQL, TurboISO, BoostISO, CFL-Match, VF3, CECI, and DAF. ### References[#](#references "Link to this heading") * Gross J., Yellen J., Anderson M. (2018). _Graph Theory and Its applications_ (3rd edition). CRC Press. * Somkunwar R., Moreshwar Vaze V. _A Comparative Study of Graph Isomorphism Applications_. International Journal of Computer Applications (0975 – 8887). Volume 162 – No 7, (March 2017) [https://www.ijcaonline.org/archives/volume162/number7/somkunwar-2017-ijca-913414.pdf](https://www.ijcaonline.org/archives/volume162/number7/somkunwar-2017-ijca-913414.pdf) * L. P. Cordella, P. Foggia, C. Sansone, M. Vento, “An Improved Algorithm for Matching Large Graphs”, IEEE Transactions on Pattern Analysis and Machine Intelligence ( Volume: 26, Issue: 10, October 2004) [https://ieeexplore.ieee.org/document/1323804](https://ieeexplore.ieee.org/document/1323804) * [https://en.wikipedia.org/wiki/Graph\_isomorphism\_problem](https://en.wikipedia.org/wiki/Graph_isomorphism_problem) Contents --- # Graph Generators — NetworkX Notebooks [Skip to main content](#main-content) Back to top Ctrl+K [![NetworkX Notebooks - Home](../../_static/networkx_banner.svg) ![NetworkX Notebooks - Home](../../_static/networkx_banner.svg)](../../index.html) * [GitHub](https://github.com/networkx/nx-guides/ "GitHub") Search Ctrl+K * [Repository](https://github.com/networkx/nx-guides "Source repository") * [Suggest edit](https://github.com/networkx/nx-guides/edit/main/site/content/generators/index.md "Suggest edit") * [Open issue](https://github.com/networkx/nx-guides/issues/new?title=Issue%20on%20page%20%2Fcontent/generators/index.html&body=Your%20issue%20content%20here. "Open an issue") * [.md](../../_sources/content/generators/index.md "Download source file") * .pdf Graph Generators ================ Graph Generators[#](#graph-generators "Link to this heading") ============================================================== A closer look at the functions provided by NetworkX to create interesting graphs. * [Geometric Generator Models](geometric.html) * [Sudoku and Graph Coloring](sudoku.html) --- # NetworkX 3.1 — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NetworkX 3.1[#](#networkx-3-1 "Link to this heading") ====================================================== Release date: 4 April 2023 Supports Python 3.8, 3.9, 3.10, and 3.11. NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. For more information, please visit our [website](https://networkx.org/) and our [gallery of examples](../auto_examples/index.html#examples-gallery) . Please send comments and questions to the [networkx-discuss mailing list](http://groups.google.com/group/networkx-discuss) . Highlights[#](#highlights "Link to this heading") -------------------------------------------------- This release is the result of 3 months of work with over 85 pull requests by 26 contributors. Highlights include: * Minor bug-fixes and speed-ups * Improvements to plugin based backend infrastructure * Minor documentation improvements * Improved test coverage * Last release supporting Python 3.8 * Stopped building PDF version of docs * Use Ruff for linting Improvements[#](#improvements "Link to this heading") ------------------------------------------------------ * \[[#6461](https://github.com/networkx/networkx/pull/6461)\ \] Add simple cycle enumerator for undirected class * \[[#6404](https://github.com/networkx/networkx/pull/6404)\ \] Add spectral bisection for graphs using fiedler vector * \[[#6244](https://github.com/networkx/networkx/pull/6244)\ \] Improve handling of create\_using to allow Mixins of type Protocol * \[[#5399](https://github.com/networkx/networkx/pull/5399)\ \] Add Laplace centrality measure Deprecations[#](#deprecations "Link to this heading") ------------------------------------------------------ * \[[#6564](https://github.com/networkx/networkx/pull/6564)\ \] Deprecate `single_target_shortest_path_length` to change return value to a dict in v3.3. Deprecate `shortest_path` in case of all\_pairs to change return value to a iterator in v3.3. * \[[#5602](https://github.com/networkx/networkx/pull/5602)\ \] Deprecate `forest_str` function (use `write_network_text` instead). Merged PRs[#](#merged-prs "Link to this heading") -------------------------------------------------- * Designate 3.0 release * Fix docs * Bump release version * Fix link in isomorphvf2.py (#6347) * Add dev release notes template * Update precommit hooks (#6348) * Add clique examples and deprecate helper functions (#6186) * Laplace centrality for issue 4973 (#5399) * doc:improve doc of possible values of nodes and expected behaviour (#6333) * add OrderedGraph removal as an API change in release\_3.0.rst (#6354) * Update release\_3.0 authors (add Jim and Erik) (#6356) * Fix broken link nx guide (#6361) * Add nx-guide link in the tutorial (#6353) * DOC: Minor formatting fixups to get rid of doc build warnings. (#6363) * Fix equation in clustering documentation (#6369) * Add reference to paper in vf2pp (#6373) * provide tikz with degrees, not radians (#6360) * Improve handling of create\_using to allow Mixins of type Protocol (#6244) * Remove an instance of random.sample from a set (deprecated in Python 3.9) (#6380) * DOC: Add banner for user survey announcement (#6375) * bump pre-commit hooks (and fix CI) (#6396) * Add generate / write “network text” (formerly graph\_str) (#5602) * Improve doc regular graphs (#6397) * Fix link vonoroi (#6398) * Document PageRank algo convergence condition (#6212) * Fix pre-commit on Python 3.10 (#6407) * DOC: list pred method for MultiDiGraphs (#6409) * Delete warning in approximation documentation (#6221) * Comment out unused unlayered dict construction. (#6411) * Update installation test instructions (#6303) * Added new tests in test\_clique.py (#6142) * Improve testing of bipartite projection. (#6196) * Add dispatching to more shortest path algorithms (#6415) * Add Plausible Analytics to our docs (#6413) * Fix docstring heading title. (#6424) * Added tests to test\_directed.py. (#6208) * Gallery example for Maximum Independent Set (#5563) * spectral bisection for graphs using fiedler vector (#6404) * Update developer requirements (#6429) * Fix reference in line.py-inverse\_line\_graph (#6434) * Add project desc for visualization and ISMAGs (#6432) * Lint using Ruff (#6371) * add ruff commit to git-blame-ignore (#6440) * NXEP 0 and NXEP 1 - change status to Accepted (#5343) * Bump gh-pages deploy bot version. (#6446) * Start using ruff for pyupgrade and isort (#6441) * Add documentation building to contributor guide (#6437) * Reset deploy-action param names for latest version. (#6451) * Doc upgrade paley graph (#6399) * Added two tests for convert\_numpy (#6455) * Clean up similarity.py and use dataclasses for storing state (#5831) * Remove pdf latex builds of docs (#5572) * Add docstring for dorogovtsev\_goltsev\_mendes generator (#6450) * Allow first argument to be passed as kwarg in dispatcher (#6471) * Fix negative edge cycle function raising exception for empty graph (#6473) * Dispatch more BFS-based algorithms (#6467) * Ignore weakrefs when testing for memory leak (#6466) * Fix reference formatting in generator docstring. (#6493) * tweak `test_override_dispatch` to allow G keyword (#6499) * Improve test coverage for astar.py (#6504) * Add docstring example to weighted.py (#6497) * Fix len operation of UnionAtlas (#6478) * Improve test coverage for edgelist.py (#6507) * Improve test coverage for mst.py and bug fix in prim\_mst\_edges() (#6486) * Add examples clarifying ambiguity of nbunch (#6513) * Updating removing explicit import for communities (#6459) * Use generator to limit memory footprint of read\_graph6. (#6519) * Update docstring of paley graph (#6529) * Fixed bug k\_truss doesn’t raise exception for self loops (#6521) * Update pre-commit (#6545) * Update sphinx (#6544) * Add docstring examples to dag.py (#6491) * Add example script for mst (#6525) * Add docstring examples to boundary.py (#6487) * improve test coverage for branchings.py (#6523) * Improve test coverage for redundancy.py (#6551) * Fixed return type inconsistencies in shortest path methods documentation (#6528) * Optimize \_single\_shortest\_path\_length function (#6299) * Deprecate shortest\_path functions to have consistent return values in v3.3 (#6567) * Add community detection example to Gallery (#6526) * add simple cycle enumerator for undirected class (#6461) * Fix survey URL (#6548) * Test dispatching via nx-loopback backend (#6536) * Fixed return type inconsistencies in weighted.py (#6568) * Update team galleries (#6569) * Added Docstring Example for Bidirectional Shortest Path (#6570) * Update release requirements (#6587) * Designate 3.1rc0 release * Bump release version * corrections to docstring of `weisfeiler_lehman_subgraph_hashes` (#6598) * Fixed method description in ismags.py (#6600) * Minor docs/test maintenance (#6614) * Better default alpha value for viz attributes in gexf writer (#6612) * Fix module docstring format for ismags reference article. (#6611) * Resolve NXEP4 with justification for not implementing it. (#6617) * Fix typos (#6620) * Draft release notes (#6621) * Prep 3.1 release Contributors[#](#contributors "Link to this heading") ------------------------------------------------------ * Navya Agarwal * Lukong Anne * Ross Barnowski * Gabor Berei * Paula Pérez Bianchi * Kelly Boothby * Purvi Chaurasia * Jon Crall * Michael Holtz * Jim Kitchen * Claudia Madrid * Jarrod Millman * Vanshika Mishra * Harri Nieminen * Tina Oberoi * Omkaar * Dima Pasechnik * Alimi Qudirah * Dan Schult * Mridul Seth * Eric Sims * Tortar * Erik Welch * Aaron Z * danieleades * stanyas On this page --- # Geometric Generator Models — NetworkX Notebooks [Skip to main content](#main-content) Back to top Ctrl+K [![NetworkX Notebooks - Home](../../_static/networkx_banner.svg) ![NetworkX Notebooks - Home](../../_static/networkx_banner.svg)](../../index.html) * [GitHub](https://github.com/networkx/nx-guides/ "GitHub") Search Ctrl+K * [![Binder logo](../../_static/images/logo_binder.svg)Binder](https://mybinder.org/v2/gh/networkx/nx-guides/main?urlpath=tree/site/content/generators/geometric.md "Launch on Binder") * [Repository](https://github.com/networkx/nx-guides "Source repository") * [Suggest edit](https://github.com/networkx/nx-guides/edit/main/site/content/generators/geometric.md "Suggest edit") * [Open issue](https://github.com/networkx/nx-guides/issues/new?title=Issue%20on%20page%20%2Fcontent/generators/geometric.html&body=Your%20issue%20content%20here. "Open an issue") * [.ipynb](../../_sources/content/generators/geometric.ipynb "Download notebook file") * [.md](../../_sources/content/generators/geometric.md "Download source file") * .pdf Geometric Generator Models ========================== Contents -------- Geometric Generator Models[#](#geometric-generator-models "Link to this heading") ================================================================================== In this tutorial, we’ll explore the geometric network generator models implemented under [`networkx/generators/geometric.py`](https://github.com/networkx/networkx/blob/main/networkx/generators/geometric.py) and apply them to a real-world use case to learn how these models can be parameterized and used. Import packages[#](#import-packages "Link to this heading") ------------------------------------------------------------ %matplotlib inline import numpy as np import matplotlib.pyplot as plt import networkx as nx Geometric/Spatial Networks[#](#geometric-spatial-networks "Link to this heading") ---------------------------------------------------------------------------------- Many real-world complex systems have spatial components constraining the network structures these types of systems can produce. Infrastructure networks such as transportation, electrical, and telecommunication systems, social networks and even our own synaptic networks are all embedded in physical space. Spatial Networks provide a framework for network models having spacial elements where nodes are embedded in space and a metric is incorporated that dictates the conditions for connection between nodes. Typically, the probability of connection is a decreasing function of the metric, with most models assuming Euclidean distance in 2-dimensions or 3-dimensions. The intuition of most Spatial Network models propose that there exists an increasing cost of connection between nodes that are further apart, though arbitrary connection probability functions can be modeled. The potential application of Spatial Networks to such a wide variety of real-world systems has motivated substainial research into these networks, with many unique but closely related models being proposed with theoretical proofs for many of their network properties. The 2010 Spatial Networks review article by Marc Barthélemy [\[1\]](#id9) provides a comprehensive overview of the field and reviews many of the most important theoretical proofs for the most common Spatial Network models. Here we explore some of the most typical Spatial Network models which have been implemented in the networkx package. These models can be classified using only three model parameters used by these different models: * \\(R\\) - The maximum connection distance, the `radius` parameter in networkx * \\(P(d\_{ij})\\) - The probability of edge connection as a function of the distance, \\(d\_{ij}\\), between nodes \\(i, j\\) where \\(i \\neq j\\), the `p_dist` parameter in networkx * \\(\\theta\\) - The node weight threshold for connection, the `theta` parameter in networkx Typically, nodes are uniformly distributed onto the unit square and node weights are sampled from some weight distribution. Distance, \\(d\_{ij}\\) is typically assumed to be the Euclidean distance, but some networkx models allow custom metrics where others only allow Minkowski distance metrics. The figure below shows the relationships between Spatial Network Models connected by their shared parameterization. ![spatial_networks](../../_images/spatial_networks.png) ### Individual Model Definitions[#](#individual-model-definitions "Link to this heading") This section summarizes the various models. The notation \\(E\_{ij}\\) indicates an edges exists between nodes \\(i\\) and \\(j\\). #### Random Geometric Graphs (\\(R\\))[#](#random-geometric-graphs-r "Link to this heading") A d-dimensional Random Geometric Graph (RGG) is a graph where each of the \\(N\\) nodes is assigned random coordinates in the box \\(\[0, 1\]^{d}\\), and only nodes “close” to each other are connected by an edge [\[2\]](#id10) . Any node within or equal to the maximum connection distance, \\(R\\), is a connected node and the structure of the network is fully defined by \\(R\\). RGGs, similar to Unit Disk Graphs [\[3\]](#id11) , have been widely used to model ad-hoc wireless networks. \\\[ E\_{ij}: d\_{ij} \\leq R \\\] #### Waxman Graphs (\\(\\alpha\\))[#](#waxman-graphs-alpha "Link to this heading") Waxman Graphs are the spatial generalization of Erdős–Rényi random graphs, where the probability of connection of nodes depends on a function of the distance between them[\[4\]](#id12) . The original edge probabiliy function proposed by Waxman is exponential in \\(d\_{ij}\\), providing two connection probability tuning parameters, \\(\\alpha\\) and \\(\\beta\\): \\\[ P(d\_{ij}) = \\beta e^{\\frac{-d\_{ij}}{L \\alpha}} \\\] Where \\(L\\) is the maximum distance between each pair of nodes. The shape of the edge probabiliy function, \\(P(d\_{ij})\\), plays the key role in determining the structure of a Waxman graph, but characterization of \\(P(d\_{ij})\\) in real-world networks still seems controversial. The most commonly studied functional families are the orginal exponential above, or power laws, \\(-{d\_{ij}}^{-\\alpha}\\). \\\[ E\_{ij} \\propto P(d\_{ij}) \\\] #### Threshold Graphs (\\(\\theta\\))[#](#threshold-graphs-theta "Link to this heading") A simple graph G is a threshold graph if we can assign weights to the vertices such that a pair of distinct vertices is adjacent exactly when the sum of their assigned weights equals or exceeds a specified threshold, \\(\\theta\\) [\[6\]](#id13) . Threshold Graphs are not themselves Spatial Networks, as they do not incorporate a specific geometry or metric, but they introduce the ability to consider node weights as part of the network model which is utilized by other Spatial Network models such as Geometric Threshold Graphs. \\\[ E\_{ij}: (w\_i + w\_j) \\geq \\theta \\\] #### Geographical Threshold Graphs (\\(P(d\_{ij}), \\theta\\))[#](#geographical-threshold-graphs-p-d-ij-theta "Link to this heading") Geographical Threshold Graphs are the geographical generalization of Threshold Graphs, where a pair of vertices with weights \\(w\_i, w\_j\\), and distance \\(d\_{ij}\\) are connected if and only if the product between the sum of weights \\(w\_i\\) and \\(w\_j\\) with the edge connection function, \\(P(d\_{ij})\\), is greater than or equal to a threshold value, \\(\\theta\\). [\[8\]](#id15) \\\[ E\_{ij}: (w\_i + w\_j) P(d\_{ij}) \\geq \\theta \\\] #### Soft Random Geometric Graphs (\\(R, P(d\_{ij})\\))[#](#soft-random-geometric-graphs-r-p-d-ij "Link to this heading") A recent extention of Random Geometric Graphs couples the influence of distance between nodes that are within the maximum connection distance, \\(R\\), to better model real-world systems where node proximity does not necessarily guarantee a connection between “close” nodes. In Soft Random Geometric Graphs, the probability of connection between nodes \\(i\\) and \\(j\\) is a function of their distance, \\(d\_{ij}, if \\)d\_{ij} \\leq R$. Otherwise, they are disconnected [\[7\]](#id14) . \\\[ E\_{ij} \\propto P(d\_{ij}) \\textrm{ if } d\_{ij} \\leq R \\\] #### Thresholded Random Geometric Graphs (\\(R, \\theta\\))[#](#thresholded-random-geometric-graphs-r-theta "Link to this heading") Thresholded Random Geometric Graphs extend RGGs to incorporate node weights into the model, where connections are only made between nodes with sufficiently powerful weights, up to a maximum connection distance between nodes [\[9\]](#id16) . \\\[ (w\_i + w\_j) \\geq \\theta \\textrm{ if } d\_{ij} \\leq R \\\] ### A Motivating Example[#](#a-motivating-example "Link to this heading") For this tutorial, we’ll use the Tesla North American Supercharger network to highlight how the various spatial network models implemented in networkx can be parameterized and used. ![spatial_networks](../../_images/NA-Supercharger_Network.jpg) The Supercharger data is obtained from supercharger.info, filtered for the Canadian and American Supercharger locations, totaling 385 Opened Superchargers as of April 2017. The collected data has been structured into a Networkx Graph which is made up of nested dictionaries keyed on the geohash of each Supercharger’s GPS coordinates which have been converted into a projected embedding onto the unit square. Node weights are the population of cities for each Supercharger, as a percent of total North American population. With this dataset, we can model the supercharger network with the various spatial networks implemented in networkx. \# Some matplotlib settings mpl\_params \= { "axes.titlesize": 20, "figure.figsize": (12, 4), } plt.rcParams.update(mpl\_params) Next, we load the data and construct the graph. \# from networkx.readwrite import json\_graph import json \# load json-ed networkx datafile with open("data/tesla\_network.json") as infile: G \= nx.json\_graph.node\_link\_graph(json.load(infile), edges\="links") print(G) Graph with 385 nodes and 0 edges \# example node data structure keyed on geohash of GPS cords G.nodes\["dr7k46ycwwb8"\] {'SC\_index': 173, 'geohash': 'dr7k46ycwwb8', 'weight': 0.00014093906625032375, 'GPS\_lon\_lat': \[-74.07126104459167, 41.49977498687804\], 'lat': 41.49977498687804, 'lon': -74.07126104459167, 'population': 28101, 'pos': \[0.8123107474668945, 0.42622282744786055\], 'GPS': \[41.49977498687804, -74.07126104459167\]} \# extract pos and weight attributes for use in models nodes \= G.nodes() pos \= nx.get\_node\_attributes(G, "pos") weight \= nx.get\_node\_attributes(G, "weight") Since we’ll be visualizing a lot of graphs, let’s define some general plotting options for consistent visualizations. node\_opts \= {"node\_size": 50, "node\_color": "r", "alpha": 0.4} edge\_opts \= {"edge\_color": "k"} Random Geometric Graphs[#](#random-geometric-graphs "Link to this heading") ---------------------------------------------------------------------------- For RGGs, we see the impact of increasing the maximum connection distance parameter `radius` in increasing the number of connections. fig, axes \= plt.subplots(2, 2, figsize\=(12, 8)) \# Params for visualizing edges alphas \= (0.8, 0.8, 0.3, 0.1) linewidths \= (0.2, 0.2, 0.1, 0.1) radii \= (0, 0.1, 0.2, 0.3) for r, ax, alpha, lw in zip(radii, axes.ravel(), alphas, linewidths): RGG \= nx.random\_geometric\_graph(nodes, radius\=r, pos\=pos) nx.draw\_networkx\_nodes(G, pos\=pos, ax\=ax, \*\*node\_opts) nx.draw\_networkx\_edges(RGG, pos\=pos, ax\=ax, alpha\=alpha, width\=lw, \*\*edge\_opts) ax.set\_title(f"$r = {r}$, {RGG.number\_of\_edges()} edges") fig.tight\_layout() ![../../_images/08e8c0607f933992af136d709c34f68588ed3abab70c55bef7c7f1f820e7b3c2.png](../../_images/08e8c0607f933992af136d709c34f68588ed3abab70c55bef7c7f1f820e7b3c2.png) \# Make edge visualization more prominent (and consistent) for the following \# examples edge\_opts\["alpha"\] \= 0.8 edge\_opts\["width"\] \= 0.2 Geographical Threshold Graphs[#](#geographical-threshold-graphs "Link to this heading") ---------------------------------------------------------------------------------------- The GTG model allows for a wide range of custom parameters including custom node positioning, weights, and a metric between nodes and the probability of connection, \\(P(d\_{ij})\\). The default \\(P(d\_{ij})\\) model is the metric value, \\(r\\), for the two connecting nodes raised to the \\(-\\alpha\\) parameter, which has a default value of 2. fig, axes \= plt.subplots(1, 2) \# Custom distance metric dist \= lambda x, y: sum(abs(a \- b) for a, b in zip(x, y)) distance\_metrics \= { "Default (Euclidean) distance metric": None, \# Euclidean distance "Custom distance metric": dist, } for (name, metric), ax in zip(distance\_metrics.items(), axes.ravel()): GTG \= nx.geographical\_threshold\_graph( nodes, 0.1, pos\=pos, weight\=weight, metric\=metric ) nx.draw\_networkx\_nodes(G, pos\=pos, ax\=ax, \*\*node\_opts) nx.draw\_networkx\_edges(GTG, pos\=pos, ax\=ax, \*\*edge\_opts) ax.set\_title(f"{name}\\n{GTG.number\_of\_edges()} edges") fig.tight\_layout() ![../../_images/bb334806c8a0ae3d0158cec83fb883e13c8bab727c03b205019d7b5a34988832.png](../../_images/bb334806c8a0ae3d0158cec83fb883e13c8bab727c03b205019d7b5a34988832.png) fig, axes \= plt.subplots(1, 2) \# Evaluate different p\_dists import math from scipy.stats import norm p\_dists \= { "p\_dist=Exponential": lambda d: math.exp(\-d), "p\_dist=Normal": norm(loc\=0.1, scale\=0.1).pdf, } for (name, p\_dist), ax in zip(p\_dists.items(), axes.ravel()): GTG \= nx.geographical\_threshold\_graph( nodes, 0.01, pos\=pos, weight\=weight, metric\=dist, p\_dist\=p\_dist ) nx.draw\_networkx\_nodes(G, pos\=pos, ax\=ax, \*\*node\_opts) nx.draw\_networkx\_edges(GTG, pos\=pos, ax\=ax, \*\*edge\_opts) ax.set\_title(f"{name}\\n{GTG.number\_of\_edges()} edges") fig.tight\_layout() ![../../_images/a1d23856f3966a0e622d26e62f4023f684f1a9dd238c63416b9097439f648581.png](../../_images/a1d23856f3966a0e622d26e62f4023f684f1a9dd238c63416b9097439f648581.png) Soft Random Geometric Graphs[#](#soft-random-geometric-graphs "Link to this heading") -------------------------------------------------------------------------------------- SRGGs utilize the maximum connection distance parameter, \\(R\\), of RGGs but provide the ability to input an arbitrary connection probability function, \\(P(d\_{ij})\\), for nodes within the maximum connection distance. The default \\(P(d\_{ij})\\) function for SRGGs in networkx is an exponential distribution with rate parameter `lambda=1`. fig, axes \= plt.subplots(1, 3) pdfs \= { "default": None, \# default: exponential distribution with \`lambda=1\` r"$e^{-10d}$": lambda d: math.exp(\-10 \* d), "norm": norm(loc\=0.1, scale\=0.1).pdf, } for (title, pdf), ax in zip(pdfs.items(), axes.ravel()): SRGG \= nx.soft\_random\_geometric\_graph(nodes, 0.1, pos\=pos, p\_dist\=pdf) nx.draw\_networkx\_nodes(G, pos\=pos, ax\=ax, \*\*node\_opts) nx.draw\_networkx\_edges(SRGG, pos\=pos, ax\=ax, \*\*edge\_opts) ax.set\_title(f"p\_dist={title}\\n{SRGG.number\_of\_edges()} edges") fig.tight\_layout() ![../../_images/b585feee80446fbcefd1c2a95dab31f4ff24981d2085b7c74f99abe1ec9849c7.png](../../_images/b585feee80446fbcefd1c2a95dab31f4ff24981d2085b7c74f99abe1ec9849c7.png) Thresholded Random Geometric Graphs[#](#thresholded-random-geometric-graphs "Link to this heading") ---------------------------------------------------------------------------------------------------- TRGGs allow for the coupling of the maximum connection distance and threshold parameters. The default weights for TRGG are drawn from an exponential distribution with rate parameter `lambda=1`. fig, axes \= plt.subplots(1, 2) \# Increased threshold parameter, theta, reduces graph connectivity thresholds \= (0.0001, 0.001) for thresh, ax in zip(thresholds, axes): TRGG \= nx.thresholded\_random\_geometric\_graph( nodes, 0.1, thresh, pos\=pos, weight\=weight ) nx.draw\_networkx\_nodes(G, pos\=pos, ax\=ax, \*\*node\_opts) nx.draw\_networkx\_edges(TRGG, pos\=pos, ax\=ax, \*\*edge\_opts) ax.set\_title(f"Threshold = {thresh}, {TRGG.number\_of\_edges()} edges") fig.tight\_layout() ![../../_images/3b47bb20d3268d65064507e24bb3eb92db629a7c603da9d2d4bc434210cbefe8.png](../../_images/3b47bb20d3268d65064507e24bb3eb92db629a7c603da9d2d4bc434210cbefe8.png) References[#](#references "Link to this heading") -------------------------------------------------- Contents --- # NetworkX 3.2 — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NetworkX 3.2[#](#networkx-3-2 "Link to this heading") ====================================================== Release date: 18 October 2023 Supports Python 3.9, 3.10, 3.11, and 3.12. NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. For more information, please visit our [website](https://networkx.org/) and our [gallery of examples](../auto_examples/index.html#examples-gallery) . Please send comments and questions to the [networkx-discuss mailing list](http://groups.google.com/group/networkx-discuss) . Highlights[#](#highlights "Link to this heading") -------------------------------------------------- * Add `@nx._dispatch` decorator to most algorithms ([#6688](https://github.com/networkx/networkx/pull/6688) ). API Changes[#](#api-changes "Link to this heading") ---------------------------------------------------- * Remove `topo_order` kwarg from `is_semiconnected` without deprecation ([#6651](https://github.com/networkx/networkx/pull/6651) ). * deprecate Edmonds class ([#6785](https://github.com/networkx/networkx/pull/6785) ). * Make weight part of the API for functions which had default assumptions ([#6814](https://github.com/networkx/networkx/pull/6814) ). * ENH: let users set a default value in get\_attr methods ([#6887](https://github.com/networkx/networkx/pull/6887) ). * Rename function `join` as `join_trees` ([#6908](https://github.com/networkx/networkx/pull/6908) ). * API: Add a decorator to deprecate positional args ([#6905](https://github.com/networkx/networkx/pull/6905) ). * Expire deprecation for `attrs` kwarg in node\_link module ([#6939](https://github.com/networkx/networkx/pull/6939) ). * Minor touchup to the sort\_neighbors deprecation ([#6942](https://github.com/networkx/networkx/pull/6942) ). * Rm deprecated `create_using` kwarg from scale\_free\_graph ([#6940](https://github.com/networkx/networkx/pull/6940) ). * Make position part of the API for geometric\_edges ([#6816](https://github.com/networkx/networkx/pull/6816) ). * Undeprecate literal\_(de)stringizer ([#6943](https://github.com/networkx/networkx/pull/6943) ). * Make new dtype param for incidence\_matrix kwarg-only ([#6954](https://github.com/networkx/networkx/pull/6954) ). * Make weight and seed for `fast_label_propagation_communities` kwarg only ([#6955](https://github.com/networkx/networkx/pull/6955) ). * API: Rm default value from time\_delta for cd\_index ([#6953](https://github.com/networkx/networkx/pull/6953) ). * Deprecate strongly\_connected\_components\_recursive ([#6957](https://github.com/networkx/networkx/pull/6957) ). * Rm deprecated clique helper functions ([#6941](https://github.com/networkx/networkx/pull/6941) ). Enhancements[#](#enhancements "Link to this heading") ------------------------------------------------------ * Update calculation of triangles ([#6258](https://github.com/networkx/networkx/pull/6258) ). * Add single\_source\_all\_shortest\_paths and all\_pairs\_all\_shortest\_paths ([#5959](https://github.com/networkx/networkx/pull/5959) ). * Add `@nx._dispatch` decorator to most algorithms ([#6688](https://github.com/networkx/networkx/pull/6688) ). * Move benchmarks inside main repo ([#6835](https://github.com/networkx/networkx/pull/6835) ). * ENH – Replaced for-loops in :function:`rescale_layout` with numpy vectorized methods ([#6879](https://github.com/networkx/networkx/pull/6879) ). * Fast label propagation algorithm for community detection ([#6843](https://github.com/networkx/networkx/pull/6843) ). * Add time series Visibility Graph generator ([#6880](https://github.com/networkx/networkx/pull/6880) ). * Random trees & forests ([#6758](https://github.com/networkx/networkx/pull/6758) ). * Add support for tuple-nodes to default gml parser ([#6950](https://github.com/networkx/networkx/pull/6950) ). * Add Kemeny’s constant ([#6929](https://github.com/networkx/networkx/pull/6929) ). * Speedup resistance\_distance ([#6925](https://github.com/networkx/networkx/pull/6925) ). * Allow graph generators and conversion functions to be dispatched ([#6876](https://github.com/networkx/networkx/pull/6876) ). * adding extendability problem (2nd try) ([#4890](https://github.com/networkx/networkx/pull/4890) ). Bug Fixes[#](#bug-fixes "Link to this heading") ------------------------------------------------ * Fixing DOT format for to\_agraph() ([#6474](https://github.com/networkx/networkx/pull/6474) ). * Remove `topo_order` kwarg from `is_semiconnected` without deprecation ([#6651](https://github.com/networkx/networkx/pull/6651) ). * Stabilize test of approximation.connected\_components ([#6715](https://github.com/networkx/networkx/pull/6715) ). * Fix minimum\_cycle\_basis and change to return cycle instead of set ([#6788](https://github.com/networkx/networkx/pull/6788) ). * Refix minimum\_cycle\_basis and scipy.sparse conversions and add tests ([#6789](https://github.com/networkx/networkx/pull/6789) ). * number\_of\_walks might use a weighted edge attribute ([#6815](https://github.com/networkx/networkx/pull/6815) ). * GML: added support for reading multi-line values ([#6837](https://github.com/networkx/networkx/pull/6837) ). * Avoid directed\_laplacian\_matrix causing nans in some cases ([#6866](https://github.com/networkx/networkx/pull/6866) ). * Add test about zero weight cycles and fix goldberg-radzik ([#6892](https://github.com/networkx/networkx/pull/6892) ). * Modify `s_metric` `normalized` default so function doesn’t raise ([#6841](https://github.com/networkx/networkx/pull/6841) ). * Error handling for invalid prufer sequence `from_prufer_sequence`: issue #6420 ([#6457](https://github.com/networkx/networkx/pull/6457) ). * FIX: Better default behaviour for percolation centrality with no node attrs ([#6894](https://github.com/networkx/networkx/pull/6894) ). * FIX: MultiDiGraphs keys got lost in weighted shortest paths ([#6963](https://github.com/networkx/networkx/pull/6963) ). * Handle edge cases in Laplacian centrality ([#6938](https://github.com/networkx/networkx/pull/6938) ). * adding a formula that ignores self-loops at the each level of directed louvain algorithm ([#6630](https://github.com/networkx/networkx/pull/6630) ). * Fix ` ````is_k_edge_connected```` ` for case of k=2 ([#7024](https://github.com/networkx/networkx/pull/7024) ). Documentation[#](#documentation "Link to this heading") -------------------------------------------------------- * Fix links in laplacian\_centrality and laplacian\_matrix ([#6623](https://github.com/networkx/networkx/pull/6623) ). * Add Greedy Coloring Example to Gallery ([#6647](https://github.com/networkx/networkx/pull/6647) ). * Add linting to contributor guide ([#6692](https://github.com/networkx/networkx/pull/6692) ). * Minor fixups to equitable\_coloring docstring ([#6673](https://github.com/networkx/networkx/pull/6673) ). * Remove survey banner ([#6818](https://github.com/networkx/networkx/pull/6818) ). * fix: make messages readable ([#6860](https://github.com/networkx/networkx/pull/6860) ). * add docs for source input of dfs\_predecessor and dfs\_successor ([#6867](https://github.com/networkx/networkx/pull/6867) ). * Clarify that basis generates simple cycles only ([#6882](https://github.com/networkx/networkx/pull/6882) ). * Revert “Clarify that basis generates simple cycles only” ([#6885](https://github.com/networkx/networkx/pull/6885) ). * updating TSP example docs ([#6794](https://github.com/networkx/networkx/pull/6794) ). * MAINT: Point the PR template to pre-commit ([#6902](https://github.com/networkx/networkx/pull/6902) ). * fix doc build errors/warnings ([#6907](https://github.com/networkx/networkx/pull/6907) ). * DOC: stray backtick and double instead of simple backtick ([#6917](https://github.com/networkx/networkx/pull/6917) ). * DOC: Add example for self loop multidigraph in contraction ([#6901](https://github.com/networkx/networkx/pull/6901) ). * Fix sphinx docs rendering of dispatched functions ([#6895](https://github.com/networkx/networkx/pull/6895) ). * added more examples on graphical degree sequence ([#5634](https://github.com/networkx/networkx/pull/5634) ). * Minor touchup to the sort\_neighbors deprecation ([#6942](https://github.com/networkx/networkx/pull/6942) ). * Warning comment for float weights in betweenness.py ([#5171](https://github.com/networkx/networkx/pull/5171) ). * DOC: Misc typos ([#6959](https://github.com/networkx/networkx/pull/6959) ). * Fixing typo in effective\_size documentation ([#6967](https://github.com/networkx/networkx/pull/6967) ). * fix examples in tournament.py ([#6964](https://github.com/networkx/networkx/pull/6964) ). * Fix a reference ([#6977](https://github.com/networkx/networkx/pull/6977) ). * Add missing parameter to snap\_aggregation docstring ([#6978](https://github.com/networkx/networkx/pull/6978) ). * Update developer deprecation todo list ([#6985](https://github.com/networkx/networkx/pull/6985) ). * Add “networkx.plugin\_info” entry point and update docstring ([#6911](https://github.com/networkx/networkx/pull/6911) ). * document graph type; add links; rm unused import ([#6992](https://github.com/networkx/networkx/pull/6992) ). * Add GraphBLAS backend to online docs ([#6998](https://github.com/networkx/networkx/pull/6998) ). * Add 3.2rc0 release notes ([#6997](https://github.com/networkx/networkx/pull/6997) ). * Update release process for changelist ([#7005](https://github.com/networkx/networkx/pull/7005) ). * Update contributing guide for changelist workflow ([#7004](https://github.com/networkx/networkx/pull/7004) ). * Fix definition of \\(m\\) parameter in docstring of `modularity` function ([#6990](https://github.com/networkx/networkx/pull/6990) ). * updated docs of SA\_tsp and TA\_tsp ([#7013](https://github.com/networkx/networkx/pull/7013) ). * Update katz\_centrality missing default alpha value ([#7015](https://github.com/networkx/networkx/pull/7015) ). Maintenance[#](#maintenance "Link to this heading") ---------------------------------------------------- * Replacing codecov Python CLI with gh action ([#6635](https://github.com/networkx/networkx/pull/6635) ). * Bump pyupgrade minimum Python version to 3.9 ([#6634](https://github.com/networkx/networkx/pull/6634) ). * MAINT: minor coverage cleanup ([#6674](https://github.com/networkx/networkx/pull/6674) ). * Rm unreachable code for validating input ([#6675](https://github.com/networkx/networkx/pull/6675) ). * Pin sphinx<7 as temporary fix for doc CI failures ([#6680](https://github.com/networkx/networkx/pull/6680) ). * Example of improving test granularity related to #5092 ([#5094](https://github.com/networkx/networkx/pull/5094) ). * MAINT: Bump scipy version and take advantage of lazy loading ([#6704](https://github.com/networkx/networkx/pull/6704) ). * Drop support for Python 3.8 per SPEC0 ([#6733](https://github.com/networkx/networkx/pull/6733) ). * Update pygraphviz ([#6724](https://github.com/networkx/networkx/pull/6724) ). * Update core dependencies per SPEC0 ([#6734](https://github.com/networkx/networkx/pull/6734) ). * Test on Python 3.12-beta2 ([#6737](https://github.com/networkx/networkx/pull/6737) ). * update the OSMnx example ([#6775](https://github.com/networkx/networkx/pull/6775) ). * Minor fixups to clear up numpy deprecation warnings ([#6776](https://github.com/networkx/networkx/pull/6776) ). * Add label-check workflow ([#6797](https://github.com/networkx/networkx/pull/6797) ). * Use dependabot ([#6799](https://github.com/networkx/networkx/pull/6799) ). * Bump webfactory/ssh-agent from 0.7.0 to 0.8.0 ([#6800](https://github.com/networkx/networkx/pull/6800) ). * Attach milestone to merged PRs ([#6802](https://github.com/networkx/networkx/pull/6802) ). * Add preserve\_all\_attrs to convert\_from\_nx to make it concise ([#6812](https://github.com/networkx/networkx/pull/6812) ). * Bump scientific-python/attach-next-milestone-action from f94a5235518d4d34911c41e19d780b8e79d42238 to bc07be829f693829263e57d5e8489f4e57d3d420 ([#6830](https://github.com/networkx/networkx/pull/6830) ). * Relax threshold in test of `betweenness_centrality` ([#6827](https://github.com/networkx/networkx/pull/6827) ). * Add @nx.\_dispatch to {single\_source,all\_pairs}\_all\_shortest\_paths, cd\_index ([#6832](https://github.com/networkx/networkx/pull/6832) ). * ci: Add distribution verification checks to nightly wheel upload ([#6831](https://github.com/networkx/networkx/pull/6831) ). * MAINT: fix link to nightly releases wheels ([#6845](https://github.com/networkx/networkx/pull/6845) ). * Don’t test numpy2 nightlies ([#6852](https://github.com/networkx/networkx/pull/6852) ). * MAINT: replace numpy aliases in scipy namespace ([#6857](https://github.com/networkx/networkx/pull/6857) ). * Unpin scipy upperbound for tests ([#6727](https://github.com/networkx/networkx/pull/6727) ). * Temporary work-around for NEP 51 numpy scalar reprs + NX doctests ([#6856](https://github.com/networkx/networkx/pull/6856) ). * Unpin numpy nightly wheels ([#6854](https://github.com/networkx/networkx/pull/6854) ). * fix: make messages readable ([#6860](https://github.com/networkx/networkx/pull/6860) ). * Revert “Pin sphinx<7 as temporary fix for doc CI failures (#6680)” ([#6859](https://github.com/networkx/networkx/pull/6859) ). * Change `_dispatch` to a class instead of a closure ([#6840](https://github.com/networkx/networkx/pull/6840) ). * Move random\_state decorators before `@nx._dispatch` ([#6878](https://github.com/networkx/networkx/pull/6878) ). * MAINT: Make GEXF and graphml writer work with numpy 2.0 ([#6900](https://github.com/networkx/networkx/pull/6900) ). * Rename function `join` as `join_trees` ([#6908](https://github.com/networkx/networkx/pull/6908) ). * add missing `join` deprecation stuff to release\_dev and conftest ([#6933](https://github.com/networkx/networkx/pull/6933) ). * MAINT: move dispatch test workflow as an independent CI job ([#6934](https://github.com/networkx/networkx/pull/6934) ). * MAINT: Use importlib.resources instead of file dunder to access files ([#6936](https://github.com/networkx/networkx/pull/6936) ). * DOC, MAINT: Deduplicate docs instructions ([#6937](https://github.com/networkx/networkx/pull/6937) ). * MAINT: Raise clean error with random\_triad for graph with <3 nodes ([#6962](https://github.com/networkx/networkx/pull/6962) ). * Update numpydoc ([#6773](https://github.com/networkx/networkx/pull/6773) ). * MAINT: update pre-commit tools deps ([#6965](https://github.com/networkx/networkx/pull/6965) ). * MAINT: Clean up commented out code in triads ([#6961](https://github.com/networkx/networkx/pull/6961) ). * MAINT: Scipy nightly failing with np alias ([#6969](https://github.com/networkx/networkx/pull/6969) ). * Bump actions/checkout from 3 to 4 ([#6970](https://github.com/networkx/networkx/pull/6970) ). * Add for testing new pydata-sphinx-theme PR ([#6982](https://github.com/networkx/networkx/pull/6982) ). * MAINT: Disable building delaunay geospatial example temporarily ([#6981](https://github.com/networkx/networkx/pull/6981) ). * Revert “MAINT: Disable building delaunay geospatial example temporarily” ([#6984](https://github.com/networkx/networkx/pull/6984) ). * Enhancements change default join trees 6947 ([#6948](https://github.com/networkx/networkx/pull/6948) ). * Update sphinx theme ([#6930](https://github.com/networkx/networkx/pull/6930) ). * Generate requirements files from pyproject.toml ([#6987](https://github.com/networkx/networkx/pull/6987) ). * Use trusted publisher ([#6988](https://github.com/networkx/networkx/pull/6988) ). * Prefer “backend” instead of “plugin” ([#6989](https://github.com/networkx/networkx/pull/6989) ). * CI: Pin scientific-python/upload-nightly-action to 0.2.0 ([#6993](https://github.com/networkx/networkx/pull/6993) ). * Support Python 3.12 ([#7009](https://github.com/networkx/networkx/pull/7009) ). * pip install nx-cugraph from git, not nightly wheels, for docs ([#7011](https://github.com/networkx/networkx/pull/7011) ). * Fix typos ([#7012](https://github.com/networkx/networkx/pull/7012) ). Other[#](#other "Link to this heading") ---------------------------------------- * Update release process ([#6622](https://github.com/networkx/networkx/pull/6622) ). * Add Lowest Common Ancestor example to Gallery ([#6542](https://github.com/networkx/networkx/pull/6542) ). * Add examples to bipartite centrality.py ([#6613](https://github.com/networkx/networkx/pull/6613) ). * Remove Python 3.8 from CI ([#6636](https://github.com/networkx/networkx/pull/6636) ). * Fix links in eigenvector.py and katz\_centrality.py ([#6640](https://github.com/networkx/networkx/pull/6640) ). * Use the correct namespace for girvan\_newman examples ([#6643](https://github.com/networkx/networkx/pull/6643) ). * Preserve node order in bipartite\_layout ([#6644](https://github.com/networkx/networkx/pull/6644) ). * Make cycle\_basis() deterministic ([#6654](https://github.com/networkx/networkx/pull/6654) ). * Added docstrings examples for clique.py ([#6576](https://github.com/networkx/networkx/pull/6576) ). * Fix output of is\_chordal for empty graphs ([#6563](https://github.com/networkx/networkx/pull/6563) ). * Allow multiple graphs for `@nx._dispatch` ([#6628](https://github.com/networkx/networkx/pull/6628) ). * Adding GitHub Links next to Dheeraj’s name in the contributors list ([#6670](https://github.com/networkx/networkx/pull/6670) ). * Adding is\_tounament to main namespace ([#6498](https://github.com/networkx/networkx/pull/6498) ). * Use unpacking operator on dicts to prevent constructing intermediate objects ([#6040](https://github.com/networkx/networkx/pull/6040) ). * Added tests to test\_correlation.py ([#6590](https://github.com/networkx/networkx/pull/6590) ). * Improve test coverage for neighbor\_degree.py ([#6589](https://github.com/networkx/networkx/pull/6589) ). * Added docstring examples for nx\_pylab.py ([#6616](https://github.com/networkx/networkx/pull/6616) ). * Improve Test Coverage for current\_flow\_closeness.py ([#6677](https://github.com/networkx/networkx/pull/6677) ). * try adding circleci artifact secret ([#6679](https://github.com/networkx/networkx/pull/6679) ). * Improve test coverage for reaching.py ([#6678](https://github.com/networkx/networkx/pull/6678) ). * added tests to euler.py ([#6608](https://github.com/networkx/networkx/pull/6608) ). * codespell: pre-commit, config, typos fixed ([#6662](https://github.com/networkx/networkx/pull/6662) ). * Improve test coverage for mst.py ([#6540](https://github.com/networkx/networkx/pull/6540) ). * Handle weights as `distance=` in testing dispatch ([#6671](https://github.com/networkx/networkx/pull/6671) ). * remove survey banner ([#6687](https://github.com/networkx/networkx/pull/6687) ). * CircleCI: add token for image redirector ([#6695](https://github.com/networkx/networkx/pull/6695) ). * MAINT: Add subgraph\_view and reverse\_view to nx namespace directly through graphviews ([#6689](https://github.com/networkx/networkx/pull/6689) ). * Added docstring example for dense.py ([#6669](https://github.com/networkx/networkx/pull/6669) ). * MAINT: Add a github action cron job to upload nightly wheels ([#6701](https://github.com/networkx/networkx/pull/6701) ). * MAINT: fix file path in nightly build workflow ([#6702](https://github.com/networkx/networkx/pull/6702) ). * Add example script for shortest path ([#6534](https://github.com/networkx/networkx/pull/6534) ). * Added doctrings for generic\_graph\_view ([#6697](https://github.com/networkx/networkx/pull/6697) ). * Doc: wrong underline length ([#6708](https://github.com/networkx/networkx/pull/6708) ). * MAINT: cron job to test against nightly deps every week ([#6705](https://github.com/networkx/networkx/pull/6705) ). * simplify stack in dfs ([#6366](https://github.com/networkx/networkx/pull/6366) ). * optimize generic\_bfs\_edges function ([#6359](https://github.com/networkx/networkx/pull/6359) ). * Optimize \_plain\_bfs functions ([#6340](https://github.com/networkx/networkx/pull/6340) ). * Added girth computation function ([#6633](https://github.com/networkx/networkx/pull/6633) ). * MAINT: Stop CI from uploading nightly on forks ([#6717](https://github.com/networkx/networkx/pull/6717) ). * Performance improvement for astar\_path ([#6723](https://github.com/networkx/networkx/pull/6723) ). * Skip scipy-1.11.0rc1 due to known issue ([#6726](https://github.com/networkx/networkx/pull/6726) ). * Add an optional argument to the incidence\_matrix function to provide … ([#6725](https://github.com/networkx/networkx/pull/6725) ). * Graph walks implementation by jfinkels & dtekinoglu ([#5908](https://github.com/networkx/networkx/pull/5908) ). * DOCS: Add walks to algorithms.index ([#6736](https://github.com/networkx/networkx/pull/6736) ). * Add note about using latex formatting in docstring in the contributor guide ([#6535](https://github.com/networkx/networkx/pull/6535) ). * Fix intersection\_all method ([#6744](https://github.com/networkx/networkx/pull/6744) ). * Fix Johnson method for unweighted graphs ([#6760](https://github.com/networkx/networkx/pull/6760) ). * MAINT: Ignore SciPy v1.11 in requirements ([#6769](https://github.com/networkx/networkx/pull/6769) ). * Replace deprecated numpy.alltrue method ([#6768](https://github.com/networkx/networkx/pull/6768) ). * keep out scipy 1.11.1 ([#6772](https://github.com/networkx/networkx/pull/6772) ). * Document additional imports required for building the documentation ([#6766](https://github.com/networkx/networkx/pull/6766) ). * modified max\_weight\_matching to be non-recursive ([#6684](https://github.com/networkx/networkx/pull/6684) ). * Rewrite NXEP 3 ([#6648](https://github.com/networkx/networkx/pull/6648) ). * Refactor edmonds algorithm ([#6743](https://github.com/networkx/networkx/pull/6743) ). * Docstring improvement for nx\_pylab.py ([#6602](https://github.com/networkx/networkx/pull/6602) ). * Use pyproject.toml ([#6774](https://github.com/networkx/networkx/pull/6774) ). * Include missing package\_data ([#6780](https://github.com/networkx/networkx/pull/6780) ). * \[BUG\] Patch doc and functionality for `is_minimal_d_separator` ([#6427](https://github.com/networkx/networkx/pull/6427) ). * Update to the documentation of eigenvector centrality ([#6009](https://github.com/networkx/networkx/pull/6009) ). * Fix typo in contributing page ([#6784](https://github.com/networkx/networkx/pull/6784) ). * Fix empty graph zero division error for louvain ([#6791](https://github.com/networkx/networkx/pull/6791) ). * Vertical chains for network text ([#6759](https://github.com/networkx/networkx/pull/6759) ). * Time dependent module ([#6682](https://github.com/networkx/networkx/pull/6682) ). * Allow user to opt out of edge attributes in from\_numpy\_array ([#6259](https://github.com/networkx/networkx/pull/6259) ). * modifies ` ````bfs_edges```` ` and adds warning to ` ````generic_bfs_edges```` ` ([#5925](https://github.com/networkx/networkx/pull/5925) ). * Spelling ([#6752](https://github.com/networkx/networkx/pull/6752) ). * Added test cases for join operation and fixed join operation to handle label\_attributes ([#6503](https://github.com/networkx/networkx/pull/6503) ). * Remove serialisation artifacts on adjacency\_graph ([#6041](https://github.com/networkx/networkx/pull/6041) ). * Patch view signature ([#6267](https://github.com/networkx/networkx/pull/6267) ). * Doc add nongraphical examples 6944 ([#6946](https://github.com/networkx/networkx/pull/6946) ). * feat: docstring examples for algorithms/operators/all.py ([#6974](https://github.com/networkx/networkx/pull/6974) ). Contributors[#](#contributors "Link to this heading") ------------------------------------------------------ 70 authors added to this release (alphabetically): * \=510 ([@diohabara](https://github.com/diohabara) ) * [@achluma](https://github.com/achluma) * [@anthonimes](https://github.com/anthonimes) * [@axtavt](https://github.com/axtavt) * [@cnfionawu](https://github.com/cnfionawu) * [@dependabot\[bot\]](https://github.com/apps/dependabot) * [@DiamondJoseph](https://github.com/DiamondJoseph) * [@gsemer](https://github.com/gsemer) * [@IbrH](https://github.com/IbrH) * [@peijenburg](https://github.com/peijenburg) * [@Tortar](https://github.com/Tortar) * Adam Li ([@adam2392](https://github.com/adam2392) ) * Adam Richardson ([@AdamWRichardson](https://github.com/AdamWRichardson) ) * Aditi Juneja ([@Schefflera-Arboricola](https://github.com/Schefflera-Arboricola) ) * AKSHAYA MADHURI ([@akshayamadhuri](https://github.com/akshayamadhuri) ) * Alex Markham ([@Alex-Markham](https://github.com/Alex-Markham) ) * Alimi Qudirah ([@Qudirah](https://github.com/Qudirah) ) * Andreas Wilm ([@andreas-wilm](https://github.com/andreas-wilm) ) * Anthony Labarre ([@alabarre](https://github.com/alabarre) ) * Arturo ([@ArturoSbr](https://github.com/ArturoSbr) ) * Dan Schult ([@dschult](https://github.com/dschult) ) * Davide Bonin ([@davidbonin92](https://github.com/davidbonin92) ) * Davide D’Ascenzo ([@Kidara](https://github.com/Kidara) ) * Dhaval Kumar ([@still-n0thing](https://github.com/still-n0thing) ) * Dheeraj Ravindranath ([@dheerajrav](https://github.com/dheerajrav) ) * Dilara Tekinoglu ([@dtekinoglu](https://github.com/dtekinoglu) ) * Efrem Braun ([@EfremBraun](https://github.com/EfremBraun) ) * Eirini Kafourou ([@eirinikafourou](https://github.com/eirinikafourou) ) * Eran Rivlis ([@erivlis](https://github.com/erivlis) ) * Erik Welch ([@eriknw](https://github.com/eriknw) ) * Evgenia Pampidi ([@evgepab](https://github.com/evgepab) ) * Florine W. Dekker ([@FWDekker](https://github.com/FWDekker) ) * Geoff Boeing ([@gboeing](https://github.com/gboeing) ) * Haoyang Li ([@thirtiseven](https://github.com/thirtiseven) ) * Ian Thompson ([@it176131](https://github.com/it176131) ) * Jarrod Millman ([@jarrodmillman](https://github.com/jarrodmillman) ) * Jeremy Foote ([@jdfoote](https://github.com/jdfoote) ) * Jim Kitchen ([@jim22k](https://github.com/jim22k) ) * Jon Crall ([@Erotemic](https://github.com/Erotemic) ) * Jordan Matelsky ([@j6k4m8](https://github.com/j6k4m8) ) * Josh Soref ([@jsoref](https://github.com/jsoref) ) * Juanita Gomez ([@juanis2112](https://github.com/juanis2112) ) * Kelly Boothby ([@boothby](https://github.com/boothby) ) * Kian-Meng Ang ([@kianmeng](https://github.com/kianmeng) ) * Koen van Walstijn ([@kbvw](https://github.com/kbvw) ) * Lovro Šubelj ([@lovre](https://github.com/lovre) ) * Lukong Anne ([@Lukong123](https://github.com/Lukong123) ) * Matt Schwennesen ([@mjschwenne](https://github.com/mjschwenne) ) * Matthew Feickert ([@matthewfeickert](https://github.com/matthewfeickert) ) * Matthias Bussonnier ([@Carreau](https://github.com/Carreau) ) * Mohamed Rezk ([@mohamedrezk122](https://github.com/mohamedrezk122) ) * Mridul Seth ([@MridulS](https://github.com/MridulS) ) * Navya Agarwal ([@navyagarwal](https://github.com/navyagarwal) ) * Nishant Bhansali ([@nishantb06](https://github.com/nishantb06) ) * Omkar Yadav ([@yadomkar](https://github.com/yadomkar) ) * Paul Brodersen ([@paulbrodersen](https://github.com/paulbrodersen) ) * Paula Pérez Bianchi ([@paulitapb](https://github.com/paulitapb) ) * Pieter Eendebak ([@eendebakpt](https://github.com/eendebakpt) ) * Pieter Kuppens ([@pkuppens](https://github.com/pkuppens) ) * Purvi Chaurasia ([@PurviChaurasia](https://github.com/PurviChaurasia) ) * Ross Barnowski ([@rossbar](https://github.com/rossbar) ) * Salim BELHADDAD ([@salym](https://github.com/salym) ) * Sebastiano Vigna ([@vigna](https://github.com/vigna) ) * Siri ([@sirichandana-v](https://github.com/sirichandana-v) ) * Stefan van der Walt ([@stefanv](https://github.com/stefanv) ) * Sultan Orazbayev ([@SultanOrazbayev](https://github.com/SultanOrazbayev) ) * Vanshika Mishra ([@vanshika230](https://github.com/vanshika230) ) * William Zijie Zhang ([@Transurgeon](https://github.com/Transurgeon) ) * Yaroslav Halchenko ([@yarikoptic](https://github.com/yarikoptic) ) * Zhaoyuan Deng ([@dzy49](https://github.com/dzy49) ) 41 reviewers added to this release (alphabetically): * [@gsemer](https://github.com/gsemer) * [@IbrH](https://github.com/IbrH) * [@peijenburg](https://github.com/peijenburg) * [@Tortar](https://github.com/Tortar) * Aaron Z. ([@aaronzo](https://github.com/aaronzo) ) * Adam Li ([@adam2392](https://github.com/adam2392) ) * Adam Richardson ([@AdamWRichardson](https://github.com/AdamWRichardson) ) * Alimi Qudirah ([@Qudirah](https://github.com/Qudirah) ) * Andreas Wilm ([@andreas-wilm](https://github.com/andreas-wilm) ) * Anthony Labarre ([@alabarre](https://github.com/alabarre) ) * Dan Schult ([@dschult](https://github.com/dschult) ) * Davide Bonin ([@davidbonin92](https://github.com/davidbonin92) ) * Dilara Tekinoglu ([@dtekinoglu](https://github.com/dtekinoglu) ) * Efrem Braun ([@EfremBraun](https://github.com/EfremBraun) ) * Eirini Kafourou ([@eirinikafourou](https://github.com/eirinikafourou) ) * Eran Rivlis ([@erivlis](https://github.com/erivlis) ) * Erik Welch ([@eriknw](https://github.com/eriknw) ) * Evgenia Pampidi ([@evgepab](https://github.com/evgepab) ) * Ian Thompson ([@it176131](https://github.com/it176131) ) * James Trimble’s ONS work ([@jtrim-ons](https://github.com/jtrim-ons) ) * Jarrod Millman ([@jarrodmillman](https://github.com/jarrodmillman) ) * Jim Kitchen ([@jim22k](https://github.com/jim22k) ) * Jordan Matelsky ([@j6k4m8](https://github.com/j6k4m8) ) * Josh Soref ([@jsoref](https://github.com/jsoref) ) * Kelly Boothby ([@boothby](https://github.com/boothby) ) * Lukong Anne ([@Lukong123](https://github.com/Lukong123) ) * Matt Schwennesen ([@mjschwenne](https://github.com/mjschwenne) ) * Matthew Feickert ([@matthewfeickert](https://github.com/matthewfeickert) ) * Matthias Bussonnier ([@Carreau](https://github.com/Carreau) ) * Mridul Seth ([@MridulS](https://github.com/MridulS) ) * Navya Agarwal ([@navyagarwal](https://github.com/navyagarwal) ) * Nishant Bhansali ([@nishantb06](https://github.com/nishantb06) ) * Orion Sehn ([@OrionSehn-personal](https://github.com/OrionSehn-personal) ) * Purvi Chaurasia ([@PurviChaurasia](https://github.com/PurviChaurasia) ) * Robert ([@ImHereForTheCookies](https://github.com/ImHereForTheCookies) ) * Ross Barnowski ([@rossbar](https://github.com/rossbar) ) * Salim BELHADDAD ([@salym](https://github.com/salym) ) * Sebastiano Vigna ([@vigna](https://github.com/vigna) ) * Sultan Orazbayev ([@SultanOrazbayev](https://github.com/SultanOrazbayev) ) * Vanshika Mishra ([@vanshika230](https://github.com/vanshika230) ) * Yaroslav Halchenko ([@yarikoptic](https://github.com/yarikoptic) ) \_These lists are automatically generated, and may not be complete or may contain duplicates.\_ On this page --- # NetworkX 3.0 — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NetworkX 3.0[#](#networkx-3-0 "Link to this heading") ====================================================== Release date: 7 January 2023 Supports Python 3.8, 3.9, 3.10, and 3.11. NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. For more information, please visit our [website](https://networkx.org/) and our [gallery of examples](../auto_examples/index.html#examples-gallery) . Please send comments and questions to the [networkx-discuss mailing list](http://groups.google.com/group/networkx-discuss) . Highlights[#](#highlights "Link to this heading") -------------------------------------------------- This release is the result of 8 months of work with over 180 changes by 41 contributors. We also have a [guide for people moving from NetworkX 2.X to NetworkX 3.0](https://networkx.org/documentation/latest/release/migration_guide_from_2.x_to_3.0.html) . Highlights include: * Better syncing between G.\_succ and G.\_adj for directed G. And slightly better speed from all the core adjacency data structures. G.adj is now a cached\_property while still having the cache reset when G.\_adj is set to a new dict (which doesn’t happen very often). Note: We have always assumed that G.\_succ and G.\_adj point to the same object. But we did not enforce it well. If you have somehow worked around our attempts and are relying on these private attributes being allowed to be different from each other due to loopholes in our previous code, you will have to look for other loopholes in our new code (or subclass DiGraph to explicitly allow this). * If your code sets G.\_succ or G.\_adj to new dictionary-like objects, you no longer have to set them both. Setting either will ensure the other is set as well. And the cached\_properties G.adj and G.succ will be rest accordingly too. * If you use the presence of the attribute `_adj` as a criteria for the object being a Graph instance, that code may need updating. The graph classes themselves now have an attribute `_adj`. So, it is possible that whatever you are checking might be a class rather than an instance. We suggest you check for attribute `_adj` to verify it is like a NetworkX graph object or type and then `type(obj) is type` to check if it is a class. * We have added an [experimental plugin feature](https://github.com/networkx/networkx/pull/6000) , which let users choose alternate backends like GraphBLAS, CuGraph for computation. This is an opt-in feature and may change in future releases. * Improved integration with the general [Scientific Python ecosystem](https://networkx.org/documentation/latest/release/migration_guide_from_2.x_to_3.0.html#improved-integration-with-scientific-python) . * New drawing feature (module and tests) from NetworkX graphs to the TikZ library of TeX/LaTeX. The basic interface is `nx.to_latex(G, pos, **options)` to construct a string of latex code or `nx.write_latex(G, filename, as_document=True, **options)` to write the string to a file. * Added an improved subgraph isomorphism algorithm called VF2++. Improvements[#](#improvements "Link to this heading") ------------------------------------------------------ * \[[#5663](https://github.com/networkx/networkx/pull/5663)\ \] Implements edge swapping for directed graphs. * \[[#5883](https://github.com/networkx/networkx/pull/5883)\ \] Replace the implementation of `lowest_common_ancestor` and `all_pairs_lowest_common_ancestor` with a “naive” algorithm to fix several bugs and improve performance. * \[[#5912](https://github.com/networkx/networkx/pull/5912)\ \] The `mapping` argument of the `relabel_nodes` function can be either a mapping or a function that creates a mapping. `relabel_nodes` first checks whether the `mapping` is callable - if so, then it is used as a function. This fixes a bug related for `mapping=str` and may change the behavior for other `mapping` arguments that implement both `__getitem__` and `__call__`. * \[[#5898](https://github.com/networkx/networkx/pull/5898)\ \] Implements computing and checking for minimal d-separators between two nodes. Also adds functionality to DAGs for computing v-structures. * \[[#5943](https://github.com/networkx/networkx/pull/5943)\ \] `is_path` used to raise a [`KeyError`](https://docs.python.org/3/library/exceptions.html#KeyError "(in Python v3.13)") when the `path` argument contained a node that was not in the Graph. The behavior has been updated so that `is_path` returns [`False`](https://docs.python.org/3/library/constants.html#False "(in Python v3.13)") in this case rather than raising the exception. * \[[#6003](https://github.com/networkx/networkx/pull/6003)\ \] `avg_shortest_path_length` now raises an exception if the provided graph is directed but not strongly connected. The previous test (weak connecting) was wrong; in that case, the returned value was nonsensical. API Changes[#](#api-changes "Link to this heading") ---------------------------------------------------- * \[[#5813](https://github.com/networkx/networkx/pull/5813)\ \] OrderedGraph and other Ordered classes are replaced by Graph because Python dicts (and thus networkx graphs) now maintain order. * \[[#5899](https://github.com/networkx/networkx/pull/5899)\ \] The `attrs` keyword argument will be replaced with keyword only arguments `source`, `target`, `name`, `key` and `link` for `json_graph/node_link` functions. Deprecations[#](#deprecations "Link to this heading") ------------------------------------------------------ * \[[#5723](https://github.com/networkx/networkx/issues/5723)\ \] `nx.nx_pydot.*` will be deprecated in the future if pydot isn’t being actively maintained. Users are recommended to use pygraphviz instead. * \[[#5899](https://github.com/networkx/networkx/pull/5899)\ \] The `attrs` keyword argument will be replaced with keyword only arguments `source`, `target`, `name`, `key` and `link` for `json_graph/node_link` functions. Merged PRs[#](#merged-prs "Link to this heading") -------------------------------------------------- * Bump release version * Add characteristic polynomial example to polynomials docs (#5730) * Remove deprecated function is\_string\_like (#5738) * Remove deprecated function make\_str (#5739) * Remove unused ‘name’ parameter from `union` (#5741) * Remove deprecated function is\_iterator (#5740) * Remove deprecated `euclidean` from geometric.py (#5744) * Remove deprecated function utils.consume (#5745) * Rm `to_numpy_recarray` (#5737) * Remove deprecated function utils.empty\_generator (#5748) * Rm jit.py (#5751) * Remove deprecated context managers (#5752) * Remove deprecated function utils.to\_tuple (#5755) * Remove deprecated display\_pygraphviz (#5754) * Remove to\_numpy\_matrix & from\_numpy\_matrix (#5746) * Remove deprecated decorator preserve\_random\_state (#5768) * Remove deprecated function is\_list\_of\_ints (#5743) * Remove decorator random\_state (#5770) * remove `adj_matrix` from `linalg/graphmatrix.py` (#5753) * Remove betweenness\_centrality\_source (#5786) * Remove deprecated simrank\_similarity\_numpy (#5783) * Remove networkx.testing subpackage (#5782) * Change PyDot PendingDeprecation to Deprecation (#5781) * Remove deprecated numeric\_mixing\_matrix (#5777) * Remove deprecated functions make\_small\_graph and make\_small\_undirected\_graph (#5761) * Remove \_naive\_greedy\_modularity\_communities (#5760) * Make chordal\_graph\_cliques a generator (#5758) * update cytoscape functions to drop old signature (#5784) * Remove deprecated functions dict\_to\_numpy\_array2 and dict\_to\_numpy\_array1 (#5756) * Remove deprecated function utils.default\_opener (#5747) * Remove deprecated function iterable (#5742) * remove old attr keyword from json\_graph/tree (#5785) * Remove generate\_unique\_node (#5780) * Replace node\_classification subpackage with a module (#5774) * Remove gpickle (#5773) * Remove deprecated function extrema\_bounding (#5757) * Remove coverage and performance from quality (#5775) * Update return type of google\_matrix to numpy.ndarray (#5762) * Remove deprecated k-nearest-neighbors (#5769) * Remove gdal dependency (#5766) * Update return type of attrmatrix (#5764) * Remove unused deprecated argument from to\_pandas\_edgelist (#5778) * Remove deprecated function edge\_betweenness (#5765) * Remove pyyaml dependency (#5763) * Remove copy methods for Filter\* coreviews (#5776) * Remove deprecated function nx.info (#5759) * Remove deprecated n\_communities argument from greedy\_modularity\_communities (#5789) * Remove deprecated functions hub\_matrix and authority\_matrix (#5767) * Make HITS numpy and scipy private functions (#5771) * Add Triad example plot (#5528) * Add gallery example visualizing DAG with multiple layouts (#5432) * Make pagerank numpy and scipy private functions (#5772) * Implement directed edge swap (#5663) * Update relabel.py to preserve node order (#5258) * Modify DAG example to show topological layout. (#5835) * Add docstring example for self-ancestors/descendants (#5802) * Update precommit linters (#5839) * remove to/from\_scipy\_sparse\_matrix (#5779) * Clean up from PR #5779 (#5841) * Corona Product (#5223) * Add direct link to github networkx org sponsorship (#5843) * added examples to efficiency\_measures.py (#5643) * added examples to regular.py (#5642) * added examples to degree\_alg.py (#5644) * Add docstring examples for triads functions (#5522) * Fix docbuild warnings: is\_string\_like is removed and indentation in corona product (#5845) * Use py\_random\_state to control randomness of random\_triad (#5847) * Remove OrderedGraphs (#5813) * Drop NumPy 1.19 (#5856) * Speed up unionfind a bit by not adding root node in the path (#5844) * Minor doc fixups (#5868) * Attempt to reverse slowdown from hasattr needed for cached\_property (#5836) * make lazy\_import private and remove its internal use (#5878) * strategy\_saturation\_largest\_first now accepts partial colorings (#5888) * Add weight distance metrics (#5305) * docstring updates for `union`, `disjoint_union`, and `compose` (#5892) * Update precommit hooks (#5923) * Remove old Appveyor cruft (#5924) * signature change for `node_link` functions: for issue #5787 (#5899) * Replace LCA with naive implementations (#5883) * Bump nodelink args deprecation expiration to v3.2 (#5933) * Update mapping logic in `relabel_nodes` (#5912) * Update pygraphviz (#5934) * Further improvements to strategy\_saturation\_largest\_first (#5935) * Arf layout (#5910) * \[ENH\] Find and verify a minimal D-separating set in DAG (#5898) * Add Mehlhorn Steiner approximations (#5629) * Preliminary VF2++ Implementation (#5788) * Minor docstring touchups and test refactor for `is_path` (#5967) * Switch to relative import for vf2pp\_helpers. (#5973) * Add vf2pp\_helpers subpackage to wheel (#5975) * Enhance biconnected components to avoid indexing (#5974) * Update mentored projects list (#5985) * Add concurrency hook to cancel jobs on new push. (#5986) * Make all.py generator friendly (#5984) * Only run scheduled pytest-randomly job in main repo. (#5993) * Fix steiner tree test (#5999) * Update doc requirements (#6008) * VF2++ for Directed Graphs (#5972) * Fix defect and update docs for MappedQueue, related to gh-5681 (#5939) * Update pydata-sphinx-theme (#6012) * Update numpydoc (#6022) * Fixed test for average shortest path in the case of directed graphs (#6003) * Update deprecations after 3.0 dep sprint (#6031) * Use scipy.sparse array datastructure (#6037) * Designate 3.0b1 release * Bump release version * Use org funding.yml * Update which flow functions support the cutoff argument (#6085) * Update GML parsing/writing to allow empty lists/tuples as node attributes (#6093) * Warn on unused visualization kwargs that only apply to FancyArrowPatch edges (#6098) * Fix weighted MultiDiGraphs in DAG longest path algorithms + add additional tests (#5988) * Circular center node layout (#6114) * Fix doc inconsistencies related to cutoff in connectivity.py and disjoint\_paths.py (#6113) * Remove deprecated maxcardinality parameter from min\_weight\_matching (#6146) * Remove deprecated `find_cores` (#6139) * Remove deprecated project function from bipartite package. (#6147) * Improve test coverage for voterank algorithm (#6161) * plugin based backend infrastructure to use multiple computation backends (#6000) * Undocumented parameters in dispersion (#6183) * Swap.py coverage to 100 (#6176) * Improve test coverage for current\_flow\_betweenness module (#6143) * Completed Testing in community.py resolves issue #6184 (#6185) * Added an example to algebraic\_connectivity (#6153) * Add ThinGraph example to Multi\*Graph doc\_strings (#6160) * Fix defect in eulerize, replace reciprocal edge weights (#6145) * For issue #6030 Add test coverage for algorithms in beamsearch.py (#6087) * Improve test coverage expanders stochastic graph generators (#6073) * Update developer requirements (#6194) * Designate 3.0rc1 release * Bump release version * Tests added in test\_centrality.py (#6200) * add laplacian\_spectrum example (#6169) * PR for issue #6033 Improve test coverage for algorithms in betweenness\_subset.py #6033 (#6083) * Di graph edges doc fix (#6108) * Improve coverage for core.py (#6116) * Add clear edges method as a method to be frozen by nx.freeze (#6190) * Adds LCA test case for self-ancestors from gh-4458. (#6218) * Minor Python 2 cleanup (#6219) * Add example laplacian matrix (#6168) * Revert 6219 and delete comment. (#6222) * fix wording in error message (#6228) * Rm incorrect test case for connected edge swap (#6223) * add missing `seed` to function called by `connected_double_edge_swap` (#6231) * Hide edges with a weight of None in A\*. (#5945) * Add dfs\_labeled\_edges reporting of reverse edges due to depth\_limit. (#6240) * Warn users about duplicate nodes in generator function input (#6237) * Re-enable geospatial examples (#6252) * Draft 3.0 release notes (#6232) * Add 2.8.x release notes (#6255) * doc: clarify allowed `alpha` when using nx.draw\_networkx\_edges (#6254) * Add a contributor (#6256) * Allow MultiDiGraphs for LCA (#6234) * Update simple\_paths.py to improve readability of the BFS. (#6273) * doc: update documentation when providing an iterator over current graph to add/remove\_edges\_from. (#6268) * Fix bug vf2pp is isomorphic issue 6257 (#6270) * Improve test coverage for Eigenvector centrality (#6227) * Bug fix in swap: directed\_edge\_swap and double\_edge\_swap (#6149) * Adding a test to verify that a NetworkXError is raised when calling n… (#6265) * Pin to sphinx 5.2.3 (#6277) * Update pre-commit hooks (#6278) * Update GH actions (#6280) * Fix links in release notes (#6281) * bug fix in smallworld.py: random\_reference and lattice\_reference (#6151) * \[DOC\] Follow numpydoc standard in barbell\_graph documentation (#6286) * Update simple\_paths.py: consistent behaviour for `is_simple_path` when path contains nodes not in the graph. (#6272) * Correctly point towards 2.8.8 in release notes (#6298) * Isomorphism improve documentation (#6295) * Improvements and test coverage for `line.py` (#6215) * Fix typo in Katz centrality comment (#6310) * Broken link in isomorphism documentation (#6296) * Update copyright years to 2023 (#6322) * fix warnings for make doctest (#6323) * fix whitespace issue in test\_internet\_as\_graph (#6324) * Create a Tikz latex drawing feature for networkx (#6238) * Fix docstrings (#6329) * Fix documentation deployment (#6330) * Fix links to migration guide (#6331) * Fix links to migration guide (#6331) * Fix typo in readme file (#6312) * Fix typos in the networkx codebase (#6335) * Refactor vf2pp modules and test files (#6334) Contributors[#](#contributors "Link to this heading") ------------------------------------------------------ * 0ddoe\_s * Abangma Jessika * Adam Li * Adam Richardson * Ali Faraji * Alimi Qudirah * Anurag Bhat * Ben Heil * Brian Hou * Casper van Elteren * danieleades * Dan Schult * ddelange * Dilara Tekinoglu * Dimitrios Papageorgiou * Douglas K. G. Araujo * Erik Welch * George Watkins * Guy Aglionby * Isaac Western * Jarrod Millman * Jim Kitchen * Juanita Gomez * Kevin Brown * Konstantinos Petridis * ladykkk * Lucas H. McCabe * Ludovic Stephan * Lukong123 * Matt Schwennesen * Michael Holtz * Morrison Turnansky * Mridul Seth * nsengaw4c * Okite chimaobi Samuel * Paula Pérez Bianchi * Radoslav Fulek * reneechebbo * Ross Barnowski * Sebastiano Vigna * stevenstrickler * Sultan Orazbayev * Tina Oberoi On this page --- # NetworkX 2.8.8 — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NetworkX 2.8.8[#](#networkx-2-8-8 "Link to this heading") ========================================================== Release date: 1 November 2022 Supports Python 3.8, 3.9, 3.10, and 3.11. NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. For more information, please visit our [website](https://networkx.org/) and our [gallery of examples](../auto_examples/index.html#examples-gallery) . Please send comments and questions to the [networkx-discuss mailing list](http://groups.google.com/group/networkx-discuss) . Highlights[#](#highlights "Link to this heading") -------------------------------------------------- Minor documentation and bug fixes. Merged PRs[#](#merged-prs "Link to this heading") -------------------------------------------------- * Bump release version * Fix warnings from running tests in randomized order (#6014) * Update pydata-sphinx-theme (#6012) * update security link to tidelift (#6019) * Update numpydoc (#6022) * Support Python 3.11 (#6023) * Update linters (#6024) * Minor updates to expanders generator tests (#6027) * Add missing asserts to tests (#6039) * fixes #6036 (#6080) * Improve test coverage expanders line graph generators solved (PR for issue #6034) (#6071) * Replace .A call with .toarray for sparse array in example. (#6106) * Improve test coverage for algorithms/richclub.py (#6089) * Tested boykov\_kolmogorov and dinitz with cutoff (#6104) * Improve test coverage for multigraph class (#6101) * Improve test coverage for algorithms in dominating\_set.py (PR for issue 6032) (#6068) * Improve test coverage for graph class (#6105) * added coverage in generators/tree.py (#6082) * DOC: Specifically branch off main, instead of current branch (#6127) * Improve test coverage for multidigraph class (#6131) * Improve test coverage for digraph class (#6130) * Improve test coverage for algorithms in dispersion.py (#6100) * Test on Python 3.11 (#6159) * Improve test coverage in algorithms shortest paths unweighted.py (#6121) * Increased test coverage algorithms/matching.py (#6095) * Renamed test functions in test\_lowest\_common\_ancestors (#6110) * Increase covering coverage (#6099) * Add example for fiedler\_vector (#6155) * Improve test coverage for cycles.py (#6152) * Added an example in all\_pairs\_node\_connectivity (#6126) * Amount of nodes and edges have mistakes when reading adjlist file (#6132) * Update pytest (#6165) Contributors[#](#contributors "Link to this heading") ------------------------------------------------------ * Ross Barnowski * Paula Pérez Bianchi * DiamondJoseph * Jarrod Millman * Mjh9122 * Alimi Qudirah * Okite chimaobi Samuel * Jefter Santiago * Dan Schult * Mridul Seth * Tindi Sommers On this page --- # Sudoku and Graph Coloring — NetworkX Notebooks [Skip to main content](#main-content) Back to top Ctrl+K [![NetworkX Notebooks - Home](../../_static/networkx_banner.svg) ![NetworkX Notebooks - Home](../../_static/networkx_banner.svg)](../../index.html) * [GitHub](https://github.com/networkx/nx-guides/ "GitHub") Search Ctrl+K * [![Binder logo](../../_static/images/logo_binder.svg)Binder](https://mybinder.org/v2/gh/networkx/nx-guides/main?urlpath=tree/site/content/generators/sudoku.md "Launch on Binder") * [Repository](https://github.com/networkx/nx-guides "Source repository") * [Suggest edit](https://github.com/networkx/nx-guides/edit/main/site/content/generators/sudoku.md "Suggest edit") * [Open issue](https://github.com/networkx/nx-guides/issues/new?title=Issue%20on%20page%20%2Fcontent/generators/sudoku.html&body=Your%20issue%20content%20here. "Open an issue") * [.ipynb](../../_sources/content/generators/sudoku.ipynb "Download notebook file") * [.md](../../_sources/content/generators/sudoku.md "Download source file") * .pdf Sudoku and Graph Coloring ========================= Contents -------- Sudoku and Graph Coloring[#](#sudoku-and-graph-coloring "Link to this heading") ================================================================================ In this tutorial, we will apply graph theory to the problem of solving a Sudoku with NetworkX. Import packages[#](#import-packages "Link to this heading") ------------------------------------------------------------ import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt import networkx as nx Introduction and Intuition[#](#introduction-and-intuition "Link to this heading") ---------------------------------------------------------------------------------- Sudoku is a popular number-placement puzzle based on logic and combinatorics. The objective is to fill a 9 × 9 grid with digits such that each column, each row, and each of the nine 3 × 3 subgrids that compose the grid contain all of the digits from 1 to 9 (once and only once). Usually the puzzle is partially filled in a way that guarantees a unique solution, as of now from what we know at least 17 cues are needed to create a puzzle with a unique solution. Another way of looking at this puzzle is as follows: * View the 81 cells as nodes of a graph * Consider the connections(being in the same row, column or grid) as edges This is the graph-theoretic framing of the problem, after this point we can treat the Sudoku as a vertex coloring problem, where we assign a color to each number(1-9) and ensure that no two nodes of the same color are connected by an edge (thus satisfying the constraints provided) > In the mathematics of Sudoku, the Sudoku graph is an undirected graph whose vertices represent the cells of a (blank) Sudoku puzzle and whose edges represent pairs of cells that belong to the same row, column, or block of the puzzle. The problem of solving a Sudoku puzzle can be represented as precoloring extension on this graph. It is an integral Cayley graph. [Wikipedia - Sudoku Graph](https://en.wikipedia.org/wiki/Sudoku_graph) Here _pre-coloring extension_ simply means translating the pre-existing cues into a graph with 81 nodes, coloring the nodes that are already given as clues, and then trying to color the rest of the vertices within the contraints. _cayley graph_ is simply a way of encoding information about group in a graph, as in we can define the sudoku puzzle completely in terms of a Graph, without missing any logical information or mathematical properties Problem Formulation[#](#problem-formulation "Link to this heading") -------------------------------------------------------------------- Informally the Sudoku graph is an undirected graph- its vertices represent the cells and edges represent pairs of cells that belong to the same row, column, or block of the puzzle. Formally this can be defined as: > A Sudoku grid of rank \\(n\\) is a \\(n^2 × n^2\\) grid(\\(X\_n\\)). It consists of \\(n^2\\) disjoint \\(n × n\\) grids. The graph of \\(X\_n\\), denoted as \\(GX\_n\\), is \\((V, E)\\) where cells of Sudoku grid form the vertices of its graph and two cells are adjacent if they are either in the same row or column or block of \\(X\_n\\). \\(GX\_n\\) is a regular \\((n^4, \\frac{3n^6}{2} − n^5− \\frac{n^4}{2})\\) graph of degree \\\[ 3n^2 − 2n − 1 (1) \\\] [Wikipedia - Sudoku Graph](https://en.wikipedia.org/wiki/Sudoku_graph) Now, from (1) we can get that the graph of a Sudoku grid of rank 3 is a \\((V=81, E=810)\\) regular graph of degree 20. This can be verified informally- we have 81 cells in the standard sudoku where every cell is adjacent to 8 cells in its row + 8 cells in its column and 4 more leftover cells in its block, hence the degree 20, [this Wikipedia figure](https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/9x9_Sudoku_graph_neighbors_%28really_fixed%29.svg/600px-9x9_Sudoku_graph_neighbors_%28really_fixed%29.svg.png) makes this visualization more understandable Let’s take an example Sudoku Puzzle that we will solve with graph theory (NetworkX and some cool figures as well!) \# Create Sudoku puzzle puzzle \= np.asarray( \[\ \[0, 4, 3, 0, 8, 0, 2, 5, 0\],\ \[6, 0, 0, 0, 0, 0, 0, 0, 0\],\ \[0, 0, 0, 0, 0, 1, 0, 9, 4\],\ \[9, 0, 0, 0, 0, 4, 0, 7, 0\],\ \[0, 0, 0, 6, 0, 8, 0, 0, 0\],\ \[0, 1, 0, 2, 0, 0, 0, 0, 3\],\ \[8, 2, 0, 5, 0, 0, 0, 0, 0\],\ \[0, 0, 0, 0, 0, 0, 0, 0, 5\],\ \[0, 3, 4, 0, 9, 0, 7, 1, 0\],\ \] ) n \= 3 G \= nx.sudoku\_graph(n) mapping \= dict(zip(G.nodes(), puzzle.flatten())) pos \= dict(zip(list(G.nodes()), nx.grid\_2d\_graph(n \* n, n \* n))) \# we map the nodes 1-9 to a colormap low, \*\_, high \= sorted(mapping.values()) norm \= mpl.colors.Normalize(vmin\=low, vmax\=high, clip\=True) mapper \= mpl.cm.ScalarMappable(norm\=norm, cmap\=mpl.cm.Pastel1) \# draw the graph plt.figure(figsize\=(12, 12)) nx.draw( G, labels\=mapping, pos\=pos, with\_labels\=True, node\_color\=\[mapper.to\_rgba(i) for i in mapping.values()\], width\=1, node\_size\=1000, ) plt.show() ![../../_images/c16f1caec1829563a81b3d9ed63099fbaf1e7c92e4385ecc56ed4d9b63b702c4.png](../../_images/c16f1caec1829563a81b3d9ed63099fbaf1e7c92e4385ecc56ed4d9b63b702c4.png) Now this can be solved using greedy graph coloring algorithms, it’s an NP hard problem, so some level of brute force is part of the process > A k-coloring of a graph G is a vertex coloring that is an assignment of one of k possible colors to each vertex of G (i.e., a vertex coloring) such that no two adjacent vertices receive the same color. How many colors would we need in this case? 9 Note: this is more than intuition, formally 9 is the chromatic number of a 2-distant coloring problem for a sudoku graph \\(n^2 \* n^2\\), you can learn more about this [here](https://mast.queensu.ca/~murty/sudoku-ams.pdf) ! Let’s generate a solved grid which we’ll try to visualize from random import sample \# Generate random sudoku def generate\_random\_sudoku(n): side \= n \* n def \_pattern(r, c): return (n \* (r % n) + r // n + c) % side rBase \= range(n) rows \= \[g \* n + r for g in sample(rBase, n) for r in sample(rBase, n)\] cols \= \[g \* n + c for g in sample(rBase, n) for c in sample(rBase, n)\] nums \= sample(range(1, n \* n + 1), n \* n) board \= \[nums\[\_pattern(r, c)\] for r in rows for c in cols\] return board So now we modify our mapping of nodes to this solved sudoku board \= generate\_random\_sudoku(n) mapping \= dict(zip(G.nodes(), board)) plt.figure(1, figsize\=(12, 12)) nx.draw( G, pos\=pos, labels\=mapping, node\_size\=1000, node\_color\=\[mapper.to\_rgba(i) for i in mapping.values()\], with\_labels\=True, ) plt.show() ![../../_images/77855569f03e0a63e1a68328f36bb6bdbfecc09007001a658ce0e2c8cdfe6ac3.png](../../_images/77855569f03e0a63e1a68328f36bb6bdbfecc09007001a658ce0e2c8cdfe6ac3.png) G \= nx.sudoku\_graph(n\=3) len(G.edges()) 810 To understand and visualize the constraints of same row, box or column, looking more carefully at the edges might be useful For starters, say we have this graph `G`, now say we want to check all the three different kinds of constraints individually, one would need to differentiate between the three different kinds of edges(there are 810!), let’s do that! Let’s just have a quick look at what networkx draws in an empty(uncolored or unlabeled) sudoku graph plt.figure(figsize\=(12, 12)) pos \= dict(zip(list(G.nodes()), nx.grid\_2d\_graph(n \* n, n \* n))) nx.draw(G, pos\=pos, node\_color\="white", with\_labels\=True) plt.show() ![../../_images/7330b9094a64d02b891b773ee33b15c3bddec926f654f572f2d4bf0d6b6337e0.png](../../_images/7330b9094a64d02b891b773ee33b15c3bddec926f654f572f2d4bf0d6b6337e0.png) There you go, so all the nodes are indexed as stacks of columns from 0 to 80, now we’ll separate the three different types of edges here import itertools def separate\_edges(n): G \= nx.sudoku\_graph(n) box\_edges \= \[\] row\_edges \= \[\] column\_edges \= \[\] boxes \= \[\] for i in range(n): for j in range(n): box \= \[\ (n) \* i + j \* (n \* n \* n) + (n \* n) \* k + l\ for k in range(n)\ for l in range(n)\ \] boxes.append(box) for i in range(n \* n): row\_edges += list( itertools.combinations(\[i + (n \* n) \* j for j in range(n \* n)\], 2) ) box\_edges += list(itertools.combinations(boxes\[i\], 2)) column\_edges += list( itertools.combinations(list(G.nodes())\[i \* (n \* n) : (i + 1) \* (n \* n)\], 2) ) return row\_edges, box\_edges, column\_edges def plot\_edge\_colored\_sudoku(n\=3, layout\="grid"): row\_edges, box\_edges, column\_edges \= separate\_edges(n) G \= nx.sudoku\_graph(n) board \= generate\_random\_sudoku(n) mapping \= dict(zip(G.nodes(), board)) plt.figure(figsize\=(12, 12)) if layout \== "circular": pos \= nx.circular\_layout(G) if layout \== "grid": pos \= dict(zip(list(G.nodes()), nx.grid\_2d\_graph(n \* n, n \* n))) nx.draw(G, pos\=pos, labels\=mapping, with\_labels\=True, node\_color\="orange") nx.draw\_networkx\_edges(G, pos\=pos, edgelist\=box\_edges, edge\_color\="tab:gray") nx.draw\_networkx\_edges( G, pos\=pos, edgelist\=row\_edges, width\=2, edge\_color\="tab:blue" ) nx.draw\_networkx\_edges( G, pos\=pos, edgelist\=column\_edges, width\=2, edge\_color\="tab:green" ) plt.show() Alright time to plot!! plot\_edge\_colored\_sudoku() ![../../_images/db13c65854d835255420f9cf0bba2826f6f20278fc205fb25cfaa1038f8eda39.png](../../_images/db13c65854d835255420f9cf0bba2826f6f20278fc205fb25cfaa1038f8eda39.png) Let’s change the layout a little to see all the edges that are invisible because they fall on top of each other plot\_edge\_colored\_sudoku(layout\="circular") ![../../_images/458bf0983a3978d75c86eab82305b95701b13f417e39e4150099f5a335bb74e8.png](../../_images/458bf0983a3978d75c86eab82305b95701b13f417e39e4150099f5a335bb74e8.png) pretty! Now, let’s check how do sudoku graphs look if sudokus were 16 x 16 grids instead of 9 x 9 plot\_edge\_colored\_sudoku(n\=4) ![../../_images/a4fd01ca304c59fcdc0d968b3ec1cfb00f9542dd32be985eda281a9181fb0854.png](../../_images/a4fd01ca304c59fcdc0d968b3ec1cfb00f9542dd32be985eda281a9181fb0854.png) References[#](#references "Link to this heading") -------------------------------------------------- [Wikipedia - Sudoku Graph](https://en.wikipedia.org/wiki/Sudoku_graph) Contents --- # NXEP 0 — Purpose and Process — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NXEP 0 — Purpose and Process[#](#nxep-0-purpose-and-process "Link to this heading") ==================================================================================== Author: Jarrod Millman <[millman@berkeley.edu](mailto:millman%40berkeley.edu) \> Status: Accepted Type: Process Created: 2020-06-25 What is a NXEP?[#](#what-is-a-nxep "Link to this heading") ----------------------------------------------------------- NXEP stands for NetworkX Enhancement Proposal. NXEPs are the primary mechanisms for proposing major new features, for collecting community input on an issue, and for documenting the design decisions that have gone into NetworkX. A NXEP should provide a concise technical specification of the feature and a rationale for the feature. The NXEP author is responsible for building consensus within the community and documenting dissenting opinions. Because the NXEPs are maintained as text files in a versioned repository, their revision history is the historical record of the feature proposal [\[1\]](#id3) . ### Types[#](#types "Link to this heading") There are three kinds of NXEPs: 1. A **Standards Track** NXEP describes a new feature or implementation for NetworkX. 2. An **Informational** NXEP describes a NetworkX design issue, or provides general guidelines or information to the Python community, but does not propose a new feature. Informational NXEPs do not necessarily represent a NetworkX community consensus or recommendation, so users and implementers are free to ignore Informational NXEPs or follow their advice. 3. A **Process** NXEP describes a process surrounding NetworkX, or proposes a change to (or an event in) a process. Process NXEPs are like Standards Track NXEPs but apply to areas other than the NetworkX language itself. They may propose an implementation, but not to NetworkX’s codebase; they require community consensus. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in NetworkX development. Any meta-NXEP is also considered a Process NXEP. NXEP Workflow[#](#nxep-workflow "Link to this heading") -------------------------------------------------------- The NXEP process begins with a new idea for NetworkX. It is highly recommended that a single NXEP contain a single key proposal or new idea. Small enhancements or patches often don’t need a NXEP and can be injected into the NetworkX development workflow with a pull request to the NetworkX [repo](https://github.com/networkx/networkx) . The more focused the NXEP, the more successful it tends to be. If in doubt, split your NXEP into several well-focused ones. Each NXEP must have a champion—someone who writes the NXEP using the style and format described below, shepherds the discussions in the appropriate forums, and attempts to build community consensus around the idea. The NXEP champion (a.k.a. Author) should first attempt to ascertain whether the idea is suitable for a NXEP. Posting to the networkx-discussion [mailing list](https://groups.google.com/group/networkx-discuss/) is the best way to go about doing this. The proposal should be submitted as a draft NXEP via a [GitHub pull request](https://github.com/networkx/networkx/pulls) to the `doc/nxeps` directory with the name `nxep-.rst` where `` is an appropriately assigned four-digit number (e.g., `nxep-0000.rst`). The draft must use the [NXEP X — Template and Instructions](nxep-template.html) file. Once the PR for the NXEP is in place, a post should be made to the mailing list containing the sections up to “Backward compatibility”, with the purpose of limiting discussion there to usage and impact. Discussion on the pull request will have a broader scope, also including details of implementation. At the earliest convenience, the PR should be merged (regardless of whether it is accepted during discussion). Additional PRs may be made by the Author to update or expand the NXEP, or by maintainers to set its status, discussion URL, etc. Standards Track NXEPs consist of two parts, a design document and a reference implementation. It is generally recommended that at least a prototype implementation be co-developed with the NXEP, as ideas that sound good in principle sometimes turn out to be impractical when subjected to the test of implementation. Often it makes sense for the prototype implementation to be made available as PR to the NetworkX repo (making sure to appropriately mark the PR as a WIP). ### Review and Resolution[#](#review-and-resolution "Link to this heading") NXEPs are discussed on the mailing list. The possible paths of the status of NXEPs are as follows: ![../../_images/nxep-0000.png](../../_images/nxep-0000.png) All NXEPs should be created with the `Draft` status. Eventually, after discussion, there may be a consensus that the NXEP should be accepted – see the next section for details. At this point the status becomes `Accepted`. Once a NXEP has been `Accepted`, the reference implementation must be completed. When the reference implementation is complete and incorporated into the main source code repository, the status will be changed to `Final`. To allow gathering of additional design and interface feedback before committing to long term stability for a language feature or standard library API, a NXEP may also be marked as “Provisional”. This is short for “Provisionally Accepted”, and indicates that the proposal has been accepted for inclusion in the reference implementation, but additional user feedback is needed before the full design can be considered “Final”. Unlike regular accepted NXEPs, provisionally accepted NXEPs may still be Rejected or Withdrawn even after the related changes have been included in a Python release. Wherever possible, it is considered preferable to reduce the scope of a proposal to avoid the need to rely on the “Provisional” status (e.g. by deferring some features to later NXEPs), as this status can lead to version compatibility challenges in the wider NetworkX ecosystem. A NXEP can also be assigned status `Deferred`. The NXEP author or a core developer can assign the NXEP this status when no progress is being made on the NXEP. A NXEP can also be `Rejected`. Perhaps after all is said and done it was not a good idea. It is still important to have a record of this fact. The `Withdrawn` status is similar—it means that the NXEP author themselves has decided that the NXEP is actually a bad idea, or has accepted that a competing proposal is a better alternative. When a NXEP is `Accepted`, `Rejected`, or `Withdrawn`, the NXEP should be updated accordingly. In addition to updating the status field, at the very least the `Resolution` header should be added with a link to the relevant thread in the mailing list archives. NXEPs can also be `Superseded` by a different NXEP, rendering the original obsolete. The `Replaced-By` and `Replaces` headers should be added to the original and new NXEPs respectively. Process NXEPs may also have a status of `Active` if they are never meant to be completed, e.g. NXEP 0 (this NXEP). ### How a NXEP becomes Accepted[#](#how-a-nxep-becomes-accepted "Link to this heading") A NXEP is `Accepted` by consensus of all interested contributors. We need a concrete way to tell whether consensus has been reached. When you think a NXEP is ready to accept, send an email to the networkx-discussion mailing list with a subject like: > Proposal to accept NXEP #: In the body of your email, you should: * link to the latest version of the NXEP, * briefly describe any major points of contention and how they were resolved, * include a sentence like: “If there are no substantive objections within 7 days from this email, then the NXEP will be accepted; see NXEP 0 for more details.” For an example, see: [https://mail.python.org/pipermail/networkx-discussion/2018-June/078345.html](https://mail.python.org/pipermail/networkx-discussion/2018-June/078345.html) After you send the email, you should make sure to link to the email thread from the `Discussion` section of the NXEP, so that people can find it later. Generally the NXEP author will be the one to send this email, but anyone can do it – the important thing is to make sure that everyone knows when a NXEP is on the verge of acceptance, and give them a final chance to respond. If there’s some special reason to extend this final comment period beyond 7 days, then that’s fine, just say so in the email. You shouldn’t do less than 7 days, because sometimes people are travelling or similar and need some time to respond. In general, the goal is to make sure that the community has consensus, not provide a rigid policy for people to try to game. When in doubt, err on the side of asking for more feedback and looking for opportunities to compromise. If the final comment period passes without any substantive objections, then the NXEP can officially be marked `Accepted`. You should send a followup email notifying the list (celebratory emoji optional but encouraged 🎉✨), and then update the NXEP by setting its `:Status:` to `Accepted`, and its `:Resolution:` header to a link to your followup email. If there _are_ substantive objections, then the NXEP remains in `Draft` state, discussion continues as normal, and it can be proposed for acceptance again later once the objections are resolved. In unusual cases, disagreements about the direction or approach may require escalation to the NetworkX [Steering Council](nxep-0001.html#steering-council) who then decide whether a controversial NXEP is `Accepted`. ### Maintenance[#](#maintenance "Link to this heading") In general, Standards track NXEPs are no longer modified after they have reached the Final state as the code and project documentation are considered the ultimate reference for the implemented feature. However, finalized Standards track NXEPs may be updated as needed. Process NXEPs may be updated over time to reflect changes to development practices and other details. The precise process followed in these cases will depend on the nature and purpose of the NXEP being updated. Format and Template[#](#format-and-template "Link to this heading") -------------------------------------------------------------------- NXEPs are UTF-8 encoded text files using the [reStructuredText](http://docutils.sourceforge.net/rst.html) format. Please see the [NXEP X — Template and Instructions](nxep-template.html) file and the [reStructuredTextPrimer](http://www.sphinx-doc.org/en/stable/rest.html) for more information. We use [Sphinx](http://www.sphinx-doc.org/en/stable/) to convert NXEPs to HTML for viewing on the web [\[2\]](#id4) . ### Header Preamble[#](#header-preamble "Link to this heading") Each NXEP must begin with a header preamble. The headers must appear in the following order. Headers marked with `*` are optional. All other headers are required. :Author: <list of authors' real names and optionally, email addresses> :Status: <Draft | Active | Accepted | Deferred | Rejected | Withdrawn | Final | Superseded\> :Type: <Standards Track | Process\> :Created: <date created on, in dd\-mmm\-yyyy format\> \* :Requires: <nxep numbers\> \* :NetworkX\-Version: <version number\> \* :Replaces: <nxep number\> \* :Replaced\-By: <nxep number\> \* :Resolution: <url\> The Author header lists the names, and optionally the email addresses of all the authors of the NXEP. The format of the Author header value must be > Random J. User <[address@dom.ain](mailto:address%40dom.ain) > \> if the email address is included, and just > Random J. User if the address is not given. If there are multiple authors, each should be on a separate line. References and Footnotes[#](#references-and-footnotes "Link to this heading") ------------------------------------------------------------------------------ On this page --- # Contributors Guide — NetworkX Notebooks [Skip to main content](#main-content) Back to top Ctrl+K [![NetworkX Notebooks - Home](../_static/networkx_banner.svg) ![NetworkX Notebooks - Home](../_static/networkx_banner.svg)](../index.html) * [GitHub](https://github.com/networkx/nx-guides/ "GitHub") Search Ctrl+K * [![Binder logo](../_static/images/logo_binder.svg)Binder](https://mybinder.org/v2/gh/networkx/nx-guides/main?urlpath=tree/site/content/contributing.md "Launch on Binder") * [Repository](https://github.com/networkx/nx-guides "Source repository") * [Suggest edit](https://github.com/networkx/nx-guides/edit/main/site/content/contributing.md "Suggest edit") * [Open issue](https://github.com/networkx/nx-guides/issues/new?title=Issue%20on%20page%20%2Fcontent/contributing.html&body=Your%20issue%20content%20here. "Open an issue") * [.ipynb](../_sources/content/contributing.ipynb "Download notebook file") * [.md](../_sources/content/contributing.md "Download source file") * .pdf Contributors Guide ================== Contents -------- Contributors Guide[#](#contributors-guide "Link to this heading") ================================================================== A Brief Roadmap for First-time Contributors[#](#a-brief-roadmap-for-first-time-contributors "Link to this heading") -------------------------------------------------------------------------------------------------------------------- The goal of nx-guides is to provide pedagogical notebooks about graph theory, network analysis, and NetworkX implementations (algorithms, etc.). This is a great place to get started with open source contribution! If you want to contribute to nx-guides and already decided on a topic to work on, here are next steps: 1. Clone `nx-guides` repository to your local machine. 2. Add your markdown notebook to the appropriate folder (i.e. if you are adding a new algorithm, add a folder with its name in `nx-guides/content/algorithms` following the structure of the other algorithms). 3. Ensure you notebook fits the Format Guidelines in this document. 4. Use subdirectories for images and data. If you use any static images and data, please put them under corresponding folders. (optional) 5. Add your notebook’s path to the index.md file. 6. When you complete your work and feel ready, push your changes to the repository and open a PR for review. 7. Engage in any discussion about your changes. Be sure to clearly communicate your thoughts. Some Tips[#](#some-tips "Link to this heading") ------------------------------------------------ ### 1\. Your notebook should be a `.md` file.[#](#your-notebook-should-be-a-md-file "Link to this heading") Your notebook should be in MyST markdown format (See: https://myst-parser.readthedocs.io/en/latest/index.html). If you normally use `.ipynb` notebooks to work on, you can convert them to `.md` using the following `jupytext` command: jupytext \--to md:myst <notebook\-name\>.ipynb ### 2\. Use code-generated images as much as possible.[#](#use-code-generated-images-as-much-as-possible "Link to this heading") Showing how to make high-quality visualizations of graph/network data is one of the primary goals of nx-guides tutorials! For this, images (especially graph visualizations) should be generated directly by code in the notebook as much as possible. If you also prefer to include static images to your notebook, you ### 3\. Add requirements to `requirements.txt`[#](#add-requirements-to-requirements-txt "Link to this heading") If you prefer to install and use other libraries, add related requirements to `requirements.txt` under `nx-guides` repository. (I.e. Do not install requirements using `pip install` command in your notebook.) ### 4\. User input is not supported yet.[#](#user-input-is-not-supported-yet "Link to this heading") Our notebooks do not support getting input from the reader yet. Although it is an idea we consider for future, please keep narrative notebooks for now. ### 5\. Do not forget to add path of your notebook to `index.md`.[#](#do-not-forget-to-add-path-of-your-notebook-to-index-md "Link to this heading") You should include the path of your notebook in index.md file under `nx-guides/content/algorithms`. ### 6\. Header Levels[#](#header-levels "Link to this heading") Header levels should be incremented one by one. If you jump from level 2 to level 4 header, for example, msyt will produce an error to prevents you from passing the tests. In this example, if the current header level is 2, the following header level needs to be either 2 or 3. ### 7\. You do not need to implement the algorithm in the same exact way as done inside NetworkX.[#](#you-do-not-need-to-implement-the-algorithm-in-the-same-exact-way-as-done-inside-networkx "Link to this heading") nx-guides provides a pedagogical source for NetworkX algorithms. For this, you do not have to include source code of the algorithm as it is under NetworkX. If possible, feel free to remove bits that you think can be better compressed :) ### 8\. Feel free to use real-world datasets[#](#feel-free-to-use-real-world-datasets "Link to this heading") One of the aims of nx-guides notebooks is to use different algorithms to explore and analyse real world datasets. Feel free to use them if you believe it is useful. Here is a good source for datasets: http://snap.stanford.edu/data/index.html ### 9\. What if the tests are still failing?[#](#what-if-the-tests-are-still-failing "Link to this heading") Once all tests are completed, you can see warnings and errors that prevents your PR from passing the tests. To do that, go to the bottom of “Conversation” page in your PR. There will be red cross signs on the left side of “ci/circleci: build-docs” test suite. Click on the “Details” link on the right side of it to see errors and warnings. You can also click on the “Details” link on the right side of “ci/circleci: build-docs artifact”. If your notebook is built, this will bring you to the full documentation for the project as if this branch was merged. You can then navigate to the notebook you have created and check that your documentation looks good. ### Environment[#](#environment "Link to this heading") A good way to go about editing your markdown file is with Jupyter Notebook or other markdown file editors. Just make sure the metadata fits that of the other markdown files in nx-guides. Format Guidelines[#](#format-guidelines "Link to this heading") ---------------------------------------------------------------- 1. Write a clear title. 2. When introducing your topic, reference what problem you are solving and what part of NetworkX you are using. 3. Include an “import packages” section at the top of the notebook after your introduction. Add all import statements for packages in a code cell underneath your introduction (see other notebooks for examples) 4. Comment code heavily, especially confusing sections. 5. Cite all sources. Include in-text references and a references section at the bottom of the document. For examples of how to write these references and cite, see other notebooks Contents --- # NXEP 1 — Governance and Decision Making — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NXEP 1 — Governance and Decision Making[#](#nxep-1-governance-and-decision-making "Link to this heading") ========================================================================================================== Author: Jarrod Millman <[millman@berkeley.edu](mailto:millman%40berkeley.edu) \> Author: Dan Schult <[dschult@colgate.edu](mailto:dschult%40colgate.edu) \> Status: Accepted Type: Process Created: 2020-06-25 Abstract[#](#abstract "Link to this heading") ---------------------------------------------- NetworkX is a consensus-based community project. Anyone with an interest in the project can join the community, contribute to the project design, and participate in the decision making process. This document describes how that participation takes place, how to find consensus, and how deadlocks are resolved. Roles And Responsibilities[#](#roles-and-responsibilities "Link to this heading") ---------------------------------------------------------------------------------- ### The Community[#](#the-community "Link to this heading") The NetworkX community consists of anyone using or working with the project in any way. ### Contributors[#](#contributors "Link to this heading") Any community member can become a contributor by interacting directly with the project in concrete ways, such as: * proposing a change to the code or documentation via a GitHub pull request; * reporting issues on our [GitHub issues page](https://github.com/networkx/networkx/issues) ; * discussing the design of the library, website, or tutorials on the [mailing list](http://groups.google.com/group/networkx-discuss/) , or in existing issues and pull requests; or * reviewing [open pull requests](https://github.com/networkx/networkx/pulls) , among other possibilities. By contributing to the project, community members can directly help to shape its future. Contributors should read the [Contributor Guide](../contribute.html#contributor-guide) and our [Code of Conduct](../code_of_conduct.html#code-of-conduct) . ### Core Developers[#](#core-developers "Link to this heading") Core developers are community members that have demonstrated continued commitment to the project through ongoing contributions. They have shown they can be trusted to maintain NetworkX with care. Becoming a core developer allows contributors to merge approved pull requests, cast votes for and against merging a pull request, and be involved in deciding major changes to the API, and thereby more easily carry on with their project related activities. Core developers appear as team members on the [NetworkX Core Developers gallery](../about_us.html#core-developers-team) and can be messaged `@networkx/core-developers`. Core developers are expected to review code contributions while adhering to the [Core Developer Guide](../core_developer.html#core-dev) . New core developers can be nominated by any existing core developer. Discussion about new core developer nominations is one of the few activities that takes place on the project’s private management list. The decision to invite a new core developer must be made by “lazy consensus”, meaning unanimous agreement by all responding existing core developers. Invitation must take place at least one week after initial nomination, to allow existing members time to voice any objections. ### Steering Council[#](#steering-council "Link to this heading") The Steering Council (SC) members are core developers who have additional responsibilities to ensure the smooth running of the project. SC members are expected to participate in strategic planning, approve changes to the governance model, and make decisions about funding granted to the project itself. (Funding to community members is theirs to pursue and manage.) The purpose of the SC is to ensure smooth progress from the big-picture perspective. Changes that impact the full project require analysis informed by long experience with both the project and the larger ecosystem. When the core developer community (including the SC members) fails to reach such a consensus in a reasonable timeframe, the SC is the entity that resolves the issue. The current list of steering council members appears on the `NetworkX Steering Council gallery` and can be messaged `@networkx/steering-council`. Decision Making Process[#](#decision-making-process "Link to this heading") ---------------------------------------------------------------------------- Decisions about the future of the project are made through discussion with all members of the community. All non-sensitive project management discussion takes place on the project [mailing list](http://groups.google.com/group/networkx-discuss/) and the [issue tracker](https://github.com/networkx/networkx/issues) . Occasionally, sensitive discussion may occur on a private list. Decisions should be made in accordance with our [Mission and Values](../values.html#mission-and-values) . NetworkX uses a _consensus seeking_ process for making decisions. The group tries to find a resolution that has no open objections among core developers. Core developers are expected to distinguish between fundamental objections to a proposal and minor perceived flaws that they can live with, and not hold up the decision making process for the latter. If no option can be found without an objection, the decision is escalated to the SC, which will itself use consensus seeking to come to a resolution. In the unlikely event that there is still a deadlock, the proposal will move forward if it has the support of a simple majority of the SC. Any proposal must be described by a NetworkX [Enhancement Proposals (NXEPs)](#nxep) . Decisions (in addition to adding core developers and SC membership as above) are made according to the following rules: * **Minor documentation changes**, such as typo fixes, or addition / correction of a sentence (but no change of the NetworkX landing page or the “about” page), require approval by a core developer _and_ no disagreement or requested changes by a core developer on the issue or pull request page (lazy consensus). Core developers are expected to give “reasonable time” to others to give their opinion on the pull request if they’re not confident others would agree. * **Code changes and major documentation changes** require agreement by _two_ core developers _and_ no disagreement or requested changes by a core developer on the issue or pull-request page (lazy consensus). * **Changes to the API principles** require a [Enhancement Proposals (NXEPs)](#nxep) and follow the decision-making process outlined above. * **Changes to this governance model or our mission and values** require a [Enhancement Proposals (NXEPs)](#nxep) and follow the decision-making process outlined above, _unless_ there is unanimous agreement from core developers on the change. If an objection is raised on a lazy consensus, the proposer can appeal to the community and core developers and the change can be approved or rejected by escalating to the SC, and if necessary, a NXEP (see below). Enhancement Proposals (NXEPs)[#](#enhancement-proposals-nxeps "Link to this heading") -------------------------------------------------------------------------------------- Any proposals for enhancements of NetworkX should be written as a formal NXEP following the template [NXEP X — Template and Instructions](nxep-template.html) . The NXEP must be made public and discussed before any vote is taken. The discussion must be summarized by a key advocate of the proposal in the appropriate section of the NXEP. Once this summary is made public and after sufficient time to allow the core team to understand it, they vote. The workflow of a NXEP is detailed in [NXEP 0 — Purpose and Process](nxep-0000.html#nxep0) . A list of all existing NXEPs is available [here](index.html#nxep-list) . Acknowledgments[#](#acknowledgments "Link to this heading") ------------------------------------------------------------ This document is based on the [scikit-image governance document](https://scikit-image.org/docs/stable/skips/1-governance.html) . On this page --- # NetworkX 2.8.6 — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NetworkX 2.8.6[#](#networkx-2-8-6 "Link to this heading") ========================================================== Release date: 22 August 2022 Supports Python 3.8, 3.9, and 3.10. NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. For more information, please visit our [website](https://networkx.org/) and our [gallery of examples](../auto_examples/index.html#examples-gallery) . Please send comments and questions to the [networkx-discuss mailing list](http://groups.google.com/group/networkx-discuss) . Highlights[#](#highlights "Link to this heading") -------------------------------------------------- Minor documentation and bug fixes. Merged PRs[#](#merged-prs "Link to this heading") -------------------------------------------------- * Add random\_spanning\_tree to documentation (#5810) * DOC: Switch to enumerated list in quotient\_graph docstring (#5837) * Add warning to nx\_agraph about layout nondeterminism. (#5832) * Update docs to include description of the `return_seen` kwarg (#5891) * Add cache reset for when G.\_node is changed (#5894) * Allow classes to relabel nodes – casting (#5903) * Update lattice.py (#5914) * Add to about\_us.rst (#5919) * Update precommit hooks (#5923) * Remove old Appveyor cruft (#5924) * signature change for `node_link` functions: for issue #5787 (#5899) * Allow unsortable nodes in approximation.treewidth functions (#5921) * Fix Louvain\_partitions by yielding a copy of the sets in the partition gh-5901 (#5902) * Adds `` `nx.bfs_layers` `` method (#5879) * Add function bfs\_layers to docs (#5932) * Propose to make new node\_link arguments keyword only. (#5928) * Bump nodelink args deprecation expiration to v3.2 (#5933) * Add examples to lowest common ancestors algorithms (#5531) * Naive lowest common ancestor implementation (#5736) * Add examples for the condensation function (#5452) * Minor doc fixups (#5868) * update all\_pairs\_lca docstrings (#5876) * Improve LCA input validation (#5877) * Replace LCA with naive implementations (#5883) * Update release notes * docstring update to lexicographical\_topological\_sort issue 5681 (#5930) * Support matplotlib 3.6rc1 failure (#5937) Improvements[#](#improvements "Link to this heading") ------------------------------------------------------ * \[[#5883](https://github.com/networkx/networkx/pull/5883)\ \] Replace the implementation of `lowest_common_ancestor` and `all_pairs_lowest_common_ancestor` with a “naive” algorithm to fix several bugs and improve performance. Contributors[#](#contributors "Link to this heading") ------------------------------------------------------ * Tanmay Aeron * Ross Barnowski * Kevin Brown * Matthias Bussonnier * Tigran Khachatryan * Dhaval Kumar * Jarrod Millman * Sultan Orazbayev * Dan Schult * Matt Schwennesen * Dilara Tekinoglu * kpetridis On this page --- # Unknown Welcome to nx-guides! ===================== \[!\[Binder\](https://mybinder.org/badge\_logo.svg)\]\[launch\_binder\] \[launch\_binder\]: https://mybinder.org/v2/gh/networkx/nx-guides/main?urlpath=lab/tree/content This site provides educational materials officially developed and curated by the NetworkX community. The goal of the repository is to provide high-quality educational resources for learning about network analysis and graph theory with NetworkX. Examples include: - Long-form narrative documentation, such as tutorials - In-depth examinations of common graph and network algorithms and their implementations in NetworkX - Demonstrations or domain-specific applications of NetworkX highlighting best-practices for network analysis. ## About The educational materials are in the form of \[markdown-based Jupyter notebooks\]\[myst-nb\], so everything is interactive! You can follow along yourself: 1. \*on binder\*, by clicking on the launch button at the top of this page, or the rocket icon in the upper-right corner of any of the pages, or 2. \*locally\*, by cloning the repository (see the octocat icon above) and running \`jupyter notebook\`. \[myst-nb\]: https://myst-nb.readthedocs.io/en/latest/authoring/text-notebooks.html ## Contents \`\`\`{toctree} --- maxdepth: 1 --- content/algorithms/index content/generators/index content/exploratory\_notebooks/facebook\_notebook content/contributing \`\`\` --- # NXEP 2 — API design of view slices — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NXEP 2 — API design of view slices[#](#nxep-2-api-design-of-view-slices "Link to this heading") ================================================================================================ Author: Mridul Seth Status: Accepted Type: Standards Track Created: 2020-07-23 Abstract[#](#abstract "Link to this heading") ---------------------------------------------- Iterating over a subset of nodes or edges in a graph is a very common operation in networkx analysis. The graph classes in NetworkX (e.g. [`Graph`](../../reference/classes/graph.html#networkx.Graph "networkx.Graph") , [`DiGraph`](../../reference/classes/digraph.html#networkx.DiGraph "networkx.DiGraph") , [`MultiGraph`](../../reference/classes/multigraph.html#networkx.MultiGraph "networkx.MultiGraph") , etc.) expose the node and edge data of the graph via [`nodes()`](../../reference/classes/generated/networkx.Graph.nodes.html#networkx.Graph.nodes "networkx.Graph.nodes") and [`edges()`](../../reference/classes/generated/networkx.Graph.edges.html#networkx.Graph.edges "networkx.Graph.edges") , which return dict view objects, `NodeView` (or `NodeDataView`) and `EdgeView` (or `EdgeDataView`), respectively. The node and edge `View` classes have dict-like semantics for item access, returning the data dict corresponding to a given node or edge. This NXEP proposes adding support for slicing to the relevant node & edge `View` classes. Motivation and Scope[#](#motivation-and-scope "Link to this heading") ---------------------------------------------------------------------- While accessing Graph data with `G.nodes` and `G.edges`, the only way of slicing the data is by casting the view to a list manually and then calling a slice on it. A slice inherently implies an ordering of the elements. We intend to use the ordering imposed on the nodes and edges by the iteration order (due to the adjacency data structure). `G.nodes(data=True)` returns a NodeDataView of all the nodes, `G.nodes(data=True)[x]` returns an attribute dictionary for the node x. The current way of getting a slice out of the underlying dict view is to cast it to list and then slice it `list(G.nodes(data=True))[0:10]`. This bit of code is something that is written a lot of times by users. For graphs with a lot of nodes and edges, `G.nodes` and `G.edges` will take a lot of screen space and when the users try to slice the resulting view (the first instinct) it will error out. Users definitely need to go through a couple of documentation links before they realise that they need to first cast this NodeDataView to a list and then create a slice. Updating the documentation to make this more clear would be helpful. But it also seems good to ease the complexity of this common idiom. In this NXEP we propose to move the casting as list inside the Node(data)View methods. Thus `list(G.nodes(data=True))[0:10]` either becomes `G.nodes(data=True)[0:10]` or it is provided by a new slicing method like `G.nodes(data=True).slice(10)` or a new slicing object to allow subscripting like `G.nodes(data=True).slice[0:10:2]`. Then users can get a small subset of nodes by creating a slice. ### Motivating Use-Case[#](#motivating-use-case "Link to this heading") It is common to use [`nodes()`](../../reference/classes/generated/networkx.Graph.nodes.html#networkx.Graph.nodes "networkx.Graph.nodes") and [`edges()`](../../reference/classes/generated/networkx.Graph.edges.html#networkx.Graph.edges "networkx.Graph.edges") when using NetworkX interactively, e.g. in a terminal. If a graph has very many components (i.e. edges or nodes) then the [`repr`](https://docs.python.org/3/library/functions.html#repr "(in Python v3.13)") of `View` object may be very long: \>>> G \= nx.complete\_graph(100) \# A graph with 4950 edges \>>> G.edges \# Output suppressed In this case, the first instinct of the user is often to inspect only the first few edges, say 10, via slicing: \>>> G.edges\[0:10\] Traceback (most recent call last) ... TypeError: cannot unpack non-iterable slice object The resulting [`TypeError`](https://docs.python.org/3/library/exceptions.html#TypeError "(in Python v3.13)") is opaque and hard to understand in the context of what was originally intended. Usage and Impact[#](#usage-and-impact "Link to this heading") -------------------------------------------------------------- The main impact and the decision that needs to be taken in this NXEP is with respect to the user facing API. By implementing this NXEP via subscripting NodeViews, we may end up adding some ambiguity for users. As for example `G.nodes[x]` will return an attribute dict but `G.nodes[0:5]` will return a list of first five nodes. This will be more ambiguous with EdgeView as `G.edges[0, 1]` will return an attribute dictionary of the edge between 0 and 1 and `G.edges[0:1]` will return the first edge. We need to find a way to counter this potential confusion. The alternative proposal of a new slicing method is one possible solution. For a historical context, in pre 2.0 NetworkX, G.nodes() and G.edges() returned lists. So, slicing was native behavior like `G.nodes()[:10]`. One caveat is that the order of that list could change from one call to the next if the adjacency structure changed between calls. In more detail, in pre 2.0 NetworkX, there were 3 ways to access node information: * `G.node` was a dict keyed by node to that node’s attribute dict as a value. * `G.nodes()` returned a list. * `G.nodes_iter()` returned an iterator over the nodes. In line with Python 3’s move toward returning dict views and iterators rather than lists, NetworkX 2.0 introduced a single interface for node information. `G.nodes` is a dict-like object keyed by node to that node’s attribute dict. It also provides set-like operations on the nodes. And it offers a method `G.nodes.data` which provides an interface similar to `dict.items` but pulling out specific attributes from the inner attribute dict rather than the entire dict. Functional synonyms `G.nodes(data="cost", default=1)` and `G.nodes.data("cost", 1)` allow an interface that looks like a dict keyed by node to a specific node attribute. Slicing was not provided in NetworkX 2.0 primarily because there was no inherent order to the nodes or edges as stored in the dict-of-dict-of-dict data structure. However, in Python 3.6, dicts became ordered based on insertion order. So, nodes are ordered based on when they were added to the graph and edges are ordered based on the adjacency dict-of-dict structure. So, there is now a concept of the “first edge”. With this NXEP we would like to bring the intuitiveness of slicing behavior back to `G.edges` and `G.nodes` using the node add order and edge order based on adjacency storage. On the computational front, if we create lists to allow slices, we use memory to store the lists. This is something user would have anyway done with something like `list(G.nodes(data=True))[0:10]`. But we can do better with our slicing mechanisms. We should be able to avoid constructing the entire list simply to get the slices by internally using code like: `indx=[n for i, n in enumerate(G.nodes(data=True)) if i in range(x.start, x.stop, s.step)]` where x is the desired slice object. Backward compatibility[#](#backward-compatibility "Link to this heading") -------------------------------------------------------------------------- N/A Detailed description[#](#detailed-description "Link to this heading") ---------------------------------------------------------------------- The new implementation will let users slice Node(Data)View and Edge(Data)View. The following code will be valid: \>>> G.nodes(data\=True)\[0:10\] \>>> G.nodes\[3:10\] \>>> G.edges\[1:10\] \>>> G.edges(data\=True)\[4:6\] Preliminary implementation work is available at [networkx/networkx#4086](https://github.com/networkx/networkx/pull/4086) Alternatively, to get rid of the ambiguity in slicing API with respect to the dict views we can implement a new `slice` method which leads to a less ambiguous API.: \>>> G.nodes(data\=True).slice\[:10\] \>>> G.nodes.slice\[10:30\] \>>> G.edges.slice\[10:40\] \>>> G.edges(data\=True).slice\[5:\] Related Work[#](#related-work "Link to this heading") ------------------------------------------------------ N/A Implementation[#](#implementation "Link to this heading") ---------------------------------------------------------- A reference implementation is proposed in [#4086](https://github.com/networkx/networkx/pull/4086/files) . The core of this NXEP is to implement `slicing` to Node(Data)View and Edge(Data)View to allow users to access a subset of nodes and edges without casting them first to a list. We will do this by adding a check of `slice` in the getitem dunder method of Node(Data)View and Edge(Data)View and returning a list of the sliced values. For example, the `__getitem__` method for `NodeView` might look something like: def \_\_getitem\_\_(self, n): if isinstance(n, slice): return list(self.\_nodes).\_\_getitem\_\_(n) return self.\_nodes\[n\] We can instead move the check for `slice` to an independent `slice` method for nodes and edges to implement this NXEP. Alternatives[#](#alternatives "Link to this heading") ------------------------------------------------------ The following list summarizes some alternatives to modifying the `__getitem__` of the various `View` classes. The listed alternatives are not mutually exclusive. * **Improved Documentation** - Add more explicit documentation about the necessity of casting Node(Data)View and Edge(Data)View objects to lists in order to be able to use slicing. * **Improved Exceptions** - Currently, users see the following exception when attempting to slice a `View`: \>>> G.nodes\[0:10\] Traceback (most recent call last) ... TypeError: unhashable type: 'slice' The exception message is not very useful in the context of accessing a subset of nodes or edges of a graph. A more specific exception message could be something along the lines of: \>>> G.nodes\[0:10\] Traceback (most recent call last) ... NetworkXError: NodeView does not support slicing. Try list(G.nodes)\[0:10\]. * Instead of changing the behavior of `__getitem__` we can implement a new method, something like `G.nodes.head(x)` (inspired by pandas) which returns the first x nodes. This approach could be expanded to using a `slice` object directly but interfacing it with an independent `slice` method of G.nodes and G.edges instead of implementing it in getitem dunder method. * The nice colon syntax for slices is only available with subscript notation. To allow G.nodes.slice to use the nice colon syntax, we could make it a property that creates a subscriptable object. Syntax would be `G.nodes.slice[4:9:2]`. Discussion[#](#discussion "Link to this heading") -------------------------------------------------- * [networkx/networkx#4086](https://github.com/networkx/networkx/pull/4086) The motivating example for the NXEP is the use-case where users want to introspect a subset (usually the first few) of the nodes and/or edges. If we look at the changes proposed by this NXEP and the listed alternatives, there are several ways that this use-case might be improved. 1. Add a descriptive error message when users try to access `View` objects with a slice object. 2. Add specialized methods to the slice object (e.g. `head()` and `tail()` or `slice()` that provide functionality useful for introspection. 3. The approach this NXEP proposes - modify `View.__getitem__` to add Sequence semantics. Option 1 (better error messages) changes neither API nor behavior and would help guide users to the correct solution for the introspection use-case. The downside is that it does not offer the same level of convenience that support for slicing does. Option 2 (`head`, `tail`, and/or `slice` methods) would add new methods to view a subset of the nodes/edges. For example: \>>> G \= nx.path\_graph(10) \>>> G.nodes() NodeView((0, 1, 2, 3, 4, 5, 6, 7, 8, 9)) \>>> G.nodes().head(3) \# Display the first three nodes NodeView((0, 1, 2)) One drawback of the approach is that is introduces new API, which has to be both discoverable and intuitive in order to make node/edge viewing more convenient. For example, is `G.nodes().head(3)` or `G.nodes().slice(0, 10, 2)` more convenient than `list(G.nodes())[:3]` or `list(G.nodes())[0:10:2]`, respectively? Another complication involves choosing the names for the new methods. `head` and `tail` are intuitive for users coming from `*nix` backgrounds and have been adopted by other popular libraries like [`pandas`](https://pandas.pydata.org/docs/index.html#module-pandas "(in pandas v2.2.3)") . However, `head` and `tail` also have meaning in the context of network science pertaining to e.g. graph edges. For example, a user might reasonably assume that `G.edges().tail()` would give the set of source nodes in a directed graph, instead of the last `n` edges. Option 3 (add sequence semantics to `View` objects) is arguably the most convenient as it doesn’t involve raising any error messages. However, overriding the behavior of `*View.__getitem__` to mix Mapping and Sequence semantics is a relatively pervasive change that may have unforeseen consequences for some use-cases. Furthermore there is precedent in Python itself for returning un-sliceable view objects from some mappings, a notable example being the `dict_keys` and `dict_values` objects returned when accessing components in dictionaries: \>>> d \= {k:v for k, v in zip(range(10), range(10))} \>>> d.values()\[3:6\] Traceback (most recent call last) ... TypeError: 'dict\_values' object is not subscriptable \>>> list(d.values())\[3:6\] \[3, 4, 5\] Since Python dictionaries are now ordered by default (as of 3.6 in CPython), this behavior may change in the future. Given the considerations associated with the listed options, the following course of action is proposed: * **Adopt option 1** - more informative error messages for the motivating use-case (e.g. `G.edges()[0:10]`) alleviates the need for users to go digging through the documentation to find/remember how to get the desired behavior. Since no new API is introduced nor are there any backwards compatibility concerns, this change doesn’t require any further design discussion. It is possible that this change is enough to resolve the motivating use-case satisfactorily - monitor user feedback. * Option 2 doesn’t require any further discussion in a design doc (i.e. NXEP). New methods along the lines discussed above can be proposed via PR. * Defer implementing option 3 for now, but reconsider if: > * The improved error message is not in itself a sufficient solution > > * Other use-cases are identified for which adding slicing to the `*View` objects would be a nice improvement (e.g. improved performance). > Resolution[#](#resolution "Link to this heading") -------------------------------------------------- To make slicing intuitive for new users, we went ahead with **Option 1** in the discussion above. Users will now see `NetworkXError` when they try to slice a `*View` object.: \>>> G.edges()\[0:10\] Traceback (most recent call last) ... NetworkXError: EdgeView does not support slicing, try list(G.edges)\[0:10:None\] The implementation is available at [networkx/networkx#4300](https://github.com/networkx/networkx/pull/4300) and [networkx/networkx#4304](https://github.com/networkx/networkx/pull/4304) . On this page --- # Facebook Network Analysis — NetworkX Notebooks [Skip to main content](#main-content) Back to top Ctrl+K [![NetworkX Notebooks - Home](../../_static/networkx_banner.svg) ![NetworkX Notebooks - Home](../../_static/networkx_banner.svg)](../../index.html) * [GitHub](https://github.com/networkx/nx-guides/ "GitHub") Search Ctrl+K * [![Binder logo](../../_static/images/logo_binder.svg)Binder](https://mybinder.org/v2/gh/networkx/nx-guides/main?urlpath=tree/site/content/exploratory_notebooks/facebook_notebook.md "Launch on Binder") * [Repository](https://github.com/networkx/nx-guides "Source repository") * [Suggest edit](https://github.com/networkx/nx-guides/edit/main/site/content/exploratory_notebooks/facebook_notebook.md "Suggest edit") * [Open issue](https://github.com/networkx/nx-guides/issues/new?title=Issue%20on%20page%20%2Fcontent/exploratory_notebooks/facebook_notebook.html&body=Your%20issue%20content%20here. "Open an issue") * [.ipynb](../../_sources/content/exploratory_notebooks/facebook_notebook.ipynb "Download notebook file") * [.md](../../_sources/content/exploratory_notebooks/facebook_notebook.md "Download source file") * .pdf Facebook Network Analysis ========================= Contents -------- Facebook Network Analysis[#](#facebook-network-analysis "Link to this heading") ================================================================================ This notebook contains a social network analysis mainly executed with the library of NetworkX. In detail, the facebook circles (friends lists) of ten people will be examined and scrutinized in order to extract all kinds of valuable information. The dataset can be found at this link: [Stanford Facebook Dataset](http://snap.stanford.edu/data/ego-Facebook.html) . Moreover, as known, a facebook network is undirected and has no weights because one user can become friends with another user just once. Looking at the dataset from a graph analysis perspective: * Each node represents an anonymized facebook user that belongs to one of those ten friends lists. * Each edge corresponds to the friendship of two facebook users that belong to this network. In other words, two users must become friends on facebook in order for them to be connected in the particular network. Note: Nodes \\(0, 107, 348, 414, 686, 698, 1684, 1912, 3437, 3980\\) are the ones whose friends list will be examined. That means that they are in the spotlight of this analysis. Those nodes are considered the `spotlight nodes` Import packages[#](#import-packages "Link to this heading") ------------------------------------------------------------ import pandas as pd import numpy as np import networkx as nx import matplotlib.pyplot as plt from random import randint %matplotlib inline Analysis[#](#analysis "Link to this heading") ---------------------------------------------- The edges are loaded from the `data` folder and saved in a dataframe. Each edge is a new row and for each edge there is a `start_node` and an `end_node` column facebook \= pd.read\_csv( "data/facebook\_combined.txt.gz", compression\="gzip", sep\=" ", names\=\["start\_node", "end\_node"\], ) facebook | | start\_node | end\_node | | --- | --- | --- | | 0 | 0 | 1 | | 1 | 0 | 2 | | 2 | 0 | 3 | | 3 | 0 | 4 | | 4 | 0 | 5 | | ... | ... | ... | | 88229 | 4026 | 4030 | | 88230 | 4027 | 4031 | | 88231 | 4027 | 4032 | | 88232 | 4027 | 4038 | | 88233 | 4031 | 4038 | 88234 rows × 2 columns The graph is created from the `facebook` dataframe of the edges: G \= nx.from\_pandas\_edgelist(facebook, "start\_node", "end\_node") Visualizing the graph[#](#visualizing-the-graph "Link to this heading") ------------------------------------------------------------------------ Let’s start our exploration by visualizing the graph. Visualization plays a central role in exploratory data analysis to help get a qualitative feel for the data. Since we don’t have any real sense of structure in the data, let’s start by viewing the graph with `random_layout`, which is among the fastest of the layout functions. fig, ax \= plt.subplots(figsize\=(15, 9)) ax.axis("off") plot\_options \= {"node\_size": 10, "with\_labels": False, "width": 0.15} nx.draw\_networkx(G, pos\=nx.random\_layout(G), ax\=ax, \*\*plot\_options) ![../../_images/a56b7271df6fb4a1c02f2869640c1a9cdca2844533f6af5c803115acce44a368.png](../../_images/a56b7271df6fb4a1c02f2869640c1a9cdca2844533f6af5c803115acce44a368.png) The resulting image is… not very useful. Graph visualizations of this kind are sometimes colloquially referred to as “hairballs” due to the overlapping edges resulting in an entangled mess. It’s clear that we need to impose more structure on the positioning of the if we want to get a sense for the data. For this, we can use the `spring_layout` function which is the default layout function for the networkx drawing module. The `spring_layout` function has the advantage that it takes into account the nodes and edges to compute locations of the nodes. The downside however, is that this process is much more computationally expensive, and can be quite slow for graphs with 100’s of nodes and 1000’s of edges. Since our dataset has over 80k edges, we will limit the number of iterations used in the `spring_layout` function to reduce the computation time. We will also save the computed layout so we can use it for future visualizations. pos \= nx.spring\_layout(G, iterations\=15, seed\=1721) fig, ax \= plt.subplots(figsize\=(15, 9)) ax.axis("off") nx.draw\_networkx(G, pos\=pos, ax\=ax, \*\*plot\_options) ![../../_images/16a767e7b6c5997b64ee3f38f7c29f7edcc5ec7387eccc5d7ce6e3aedd78f939.png](../../_images/16a767e7b6c5997b64ee3f38f7c29f7edcc5ec7387eccc5d7ce6e3aedd78f939.png) This visualization is much more useful than the previous one! Already we can glean something about the structure of the network; for example, many of the nodes seem to be highly connected, as we might expect for a social network. We also get a sense that the nodes tend to form clusters. The `spring_layout` serves to give a qualitative sense of clustering, but it is not designed for repeatable, qualitative clustering analysis. We’ll revisit evaluating network clustering [later in the analysis](#clustering-effects) Basic topological attributes[#](#basic-topological-attributes "Link to this heading") -------------------------------------------------------------------------------------- Total number of nodes in network: G.number\_of\_nodes() 4039 Total number of edges: G.number\_of\_edges() 88234 Also, the average degree of a node can be seen. * On average, a node is connected to almost 44 other nodes, also known as neighbors of the node. * This has been calculated by creating a list of all the degrees of the nodes and using `numpy.array` to find the mean of the created list. np.mean(\[d for \_, d in G.degree()\]) np.float64(43.69101262688784) There are many interesting properties related to the distribution of _paths_ through the graph. For example, the _diameter_ of a graph represents the longest of the shortest-paths that connect any node to another node in the Graph. Similarly, the average path length gives a measure of the average number of edges to be traversed to get from one node to another in the network. These attributes can be calculated with the `nx.diameter` and `nx.average_shortest_path_length` functions, respectively. Note however that these analyses require computing the shortest path between every pair of nodes in the network: this can be quite expensive for networks of this size! Since we’re interested in several analyses involving the shortest path length for all nodes in the network, we can instead compute this once and reuse the information to save computation time. Let’s start by computing the shortest path length for all pairs of nodes in the network: shortest\_path\_lengths \= dict(nx.all\_pairs\_shortest\_path\_length(G)) `nx.all_pairs_shortest_path_length` returns a dict-of-dict that maps a node `u` to all other nodes in the network, where the inner-most mapping returns the length of the shortest path between the two nodes. In other words, `shortest_path_lengths[u][v]` will return the shortest path length between any two pair of nodes `u` and `v`: shortest\_path\_lengths\[0\]\[42\] \# Length of shortest path between nodes 0 and 42 1 Now let’s use `shortest_path_lengths` to perform our analyses, starting with the _diameter_ of `G`. If we look carefully at the [docstring for `nx.diameter`](https://networkx.org/documentation/latest/reference/algorithms/generated/networkx.algorithms.distance_measures.diameter.html) , we see that it is equivalent to the maximum _eccentricity_ of the graph. It turns out that `nx.eccentricity` has an optional argument `sp` where we can pass in our pre-computed `shortest_path_lengths` to save the extra computation: \# This is equivalent to \`diameter = nx.diameter(G), but much more efficient since we're \# reusing the pre-computed shortest path lengths! diameter \= max(nx.eccentricity(G, sp\=shortest\_path\_lengths).values()) diameter 8 In order to connect from one node to any other one we would have to traverse 8 edges or fewer. Next up, the average path length is found. Again, we could use `nx.average_shortest_path_length` to compute this directly, but it’s much more efficient to use the `shortest_path_length` that we’ve already computed: \# Compute the average shortest path length for each node average\_path\_lengths \= \[\ np.mean(list(spl.values())) for spl in shortest\_path\_lengths.values()\ \] \# The average over all nodes np.mean(average\_path\_lengths) np.float64(3.691592636562027) This represents the average of the shortest path length for all pairs of nodes: in order to reach from one node to another node, roughly 3.6 edges will be traversed on average. The above measures capture useful information about the network, but metrics like the average value represent only a moment of the distribution; it is also often valuable to look at the _distribution_ itself. Again, we can construct a visualization of the distribution of shortest path lengths from our pre-computed dict-of-dicts: \# We know the maximum shortest path length (the diameter), so create an array \# to store values from 0 up to (and including) diameter path\_lengths \= np.zeros(diameter + 1, dtype\=int) \# Extract the frequency of shortest path lengths between two nodes for pls in shortest\_path\_lengths.values(): pl, cnts \= np.unique(list(pls.values()), return\_counts\=True) path\_lengths\[pl\] += cnts \# Express frequency distribution as a percentage (ignoring path lengths of 0) freq\_percent \= 100 \* path\_lengths\[1:\] / path\_lengths\[1:\].sum() \# Plot the frequency distribution (ignoring path lengths of 0) as a percentage fig, ax \= plt.subplots(figsize\=(15, 8)) ax.bar(np.arange(1, diameter + 1), height\=freq\_percent) ax.set\_title( "Distribution of shortest path length in G", fontdict\={"size": 35}, loc\="center" ) ax.set\_xlabel("Shortest Path Length", fontdict\={"size": 22}) ax.set\_ylabel("Frequency (%)", fontdict\={"size": 22}) Text(0, 0.5, 'Frequency (%)') ![../../_images/1bb6de3b726b1a8be6a1f09d07b7589f3c047b5c5a0a901d0fc4dd35ce3f37b1.png](../../_images/1bb6de3b726b1a8be6a1f09d07b7589f3c047b5c5a0a901d0fc4dd35ce3f37b1.png) The majority of the shortest path lengths are from \\(2\\) to \\(5\\) edges long. Also, it’s highly unlikely for a pair of nodes to have a shortest path of length 8 (diameter length) as the likelihood is less than \\(0.1\\)%. The graph’s density is calculated here. Clearly, the graph is a very sparse one as: \\(density < 1\\) nx.density(G) 0.010819963503439287 The graph’s number of components are found below. As expected, the network consists of one giant component: nx.number\_connected\_components(G) 1 Centrality measures[#](#centrality-measures "Link to this heading") -------------------------------------------------------------------- Now the centrality measures will be examined for the facebook graph ### Degree Centrality[#](#degree-centrality "Link to this heading") Degree centrality assigns an importance score based simply on the number of links held by each node. In this analysis, that means that the higher the degree centrality of a node is, the more edges are connected to the particular node and thus the more neighbor nodes (facebook friends) this node has. In fact, the degree of centrality of a node is the fraction of nodes it is connected to. In other words, it is the percentage of the network that the particular node is connected to meaning being friends with. * Starting, we find the nodes with the highest degree centralities. Specifically, the nodes with the 8 highest degree centralities are shown below together with the degree centrality: degree\_centrality \= nx.centrality.degree\_centrality( G ) \# save results in a variable to use again (sorted(degree\_centrality.items(), key\=lambda item: item\[1\], reverse\=True))\[:8\] \[(107, 0.258791480931154),\ (1684, 0.1961367013372957),\ (1912, 0.18697374938088163),\ (3437, 0.13546310054482416),\ (0, 0.08593363051015354),\ (2543, 0.07280832095096582),\ (2347, 0.07206537890044576),\ (1888, 0.0629024269440317)\] That means that node \\(107\\) has the highest degree centrality with \\(0.259\\), meaning that this facebook user is friends with around the 26% of the whole network. Similarly, nodes \\(1684, 1912, 3437\\) and \\(0\\) also have very high degree centralities. However, that is well expected as those nodes are the ones whose facebook circles we examine. Very interesting is the fact that the nodes \\(2543, 2347, 1888\\) have some of the top 8 highest degree centralities even though we do not investigate their circles. In other words, those three nodes are very popular among the circles we examine now, meaning they have the most facebook friends inside this network apart from the spotlight nodes. * Now we can also see the number of neighbors for the nodes with the highest degree centralities: (sorted(G.degree, key\=lambda item: item\[1\], reverse\=True))\[:8\] \[(107, 1045),\ (1684, 792),\ (1912, 755),\ (3437, 547),\ (0, 347),\ (2543, 294),\ (2347, 291),\ (1888, 254)\] As expected, node \\(107\\) has \\(1045\\) facebook friends which is the most any facebook user has in this analysis. Moreover, nodes \\(1684\\) and \\(1912\\) have more than \\(750\\) facebook friends in this network. Also, nodes \\(3437\\) and \\(0\\) have the following highest number of facebook friends in this network with \\(547\\) and \\(347\\) respectively. Lastly, the two most popular friends of spotlight nodes have around \\(290\\) facebook friends in this network. Now the distribution of degree centralities will be plotted: plt.figure(figsize\=(15, 8)) plt.hist(degree\_centrality.values(), bins\=25) plt.xticks(ticks\=\[0, 0.025, 0.05, 0.1, 0.15, 0.2\]) \# set the x axis ticks plt.title("Degree Centrality Histogram ", fontdict\={"size": 35}, loc\="center") plt.xlabel("Degree Centrality", fontdict\={"size": 20}) plt.ylabel("Counts", fontdict\={"size": 20}) Text(0, 0.5, 'Counts') ![../../_images/08fb6ca44deb7c9e1fac7699d6421602632994adf6fb8766f5eb618d2bab1862.png](../../_images/08fb6ca44deb7c9e1fac7699d6421602632994adf6fb8766f5eb618d2bab1862.png) It is visible that the vast majority of facebook users have degree centralities of less than \\(0.05\\). In fact the majority has less than \\(0.0125\\). Actually, that makes sense because the network consists of friends lists of particular nodes, which are obviously the ones with the highest degree centralities. In other words, because only the friends list of particular nodes were used to create this particular network, plenty of nodes have extremely low degree centralities as they are not very interconnected in this network Now let’s check the users with highest degree centralities from the size of their nodes: node\_size \= \[\ v \* 1000 for v in degree\_centrality.values()\ \] \# set up nodes size for a nice graph representation plt.figure(figsize\=(15, 8)) nx.draw\_networkx(G, pos\=pos, node\_size\=node\_size, with\_labels\=False, width\=0.15) plt.axis("off") (np.float64(-0.9991946166753769), np.float64(1.1078343337774277), np.float64(-1.1645995157957079), np.float64(0.7322139519453049)) ![../../_images/0f875072c65a5d59ad26e8977d524c187f91e84d812ac646d4e3383802eeb933.png](../../_images/0f875072c65a5d59ad26e8977d524c187f91e84d812ac646d4e3383802eeb933.png) ### Betweenness Centrality[#](#betweenness-centrality "Link to this heading") Betweenness centrality measures the number of times a node lies on the shortest path between other nodes, meaning it acts as a bridge. In detail, betweenness centrality of a node \\(v\\) is the percentage of all the shortest paths of any two nodes (apart from \\(v\\)), which pass through \\(v\\). Specifically, in the facebook graph this measure is associated with the user’s ability to influence others. A user with a high betweenness centrality acts as a bridge to many users that are not friends and thus has the ability to influence them by conveying information (e.g. by posting something or sharing a post) or even connect them via the user’s circle (which would reduce the user’s betweeness centrality after). * Now, the nodes with the \\(8\\) highest betweenness centralities will be calculated and shown with their centrality values: betweenness\_centrality \= nx.centrality.betweenness\_centrality( G ) \# save results in a variable to use again (sorted(betweenness\_centrality.items(), key\=lambda item: item\[1\], reverse\=True))\[:8\] \[(107, 0.4805180785560152),\ (1684, 0.3377974497301992),\ (3437, 0.23611535735892905),\ (1912, 0.2292953395868782),\ (1085, 0.14901509211665306),\ (0, 0.14630592147442917),\ (698, 0.11533045020560802),\ (567, 0.09631033121856215)\] Looking at the results, the node \\(107\\) has a betweenness centrality of \\(0.48\\), meaning it lies on almost half of the total shortest paths between other nodes. Also, combining the knowledge of the degree centrality: * Nodes \\(0, 107, 1684, 1912, 3437\\) have both the highest degree and betweenness centralities and are `spotlight nodes`. That indicates that those nodes are both the most popular ones in this network and can also influence and spread information in the network. However, those are some of the nodes whose friends list consist the network and as a result it is an expected finding. * Nodes \\(567, 1085\\) are not spotlight nodes, have some of the highest betweenness centralities and have not the highest degree centralities. That means that even though those nodes are not the most popular users in the network, they have the most influence in this network among friends of spotlight nodes when it comes to spreading information. * Node \\(698\\) is a `spotlight node` and has a very high betweenness centrality even though it has not the highest degree centralities. In other words, this node does not have a very large friends list on facebook. However, the user’s whole friend list is a part of the network and thus the user could connect different circles in this network by being the middleman. Moving on, the distribution of betweenness centralities will be plotted: plt.figure(figsize\=(15, 8)) plt.hist(betweenness\_centrality.values(), bins\=100) plt.xticks(ticks\=\[0, 0.02, 0.1, 0.2, 0.3, 0.4, 0.5\]) \# set the x axis ticks plt.title("Betweenness Centrality Histogram ", fontdict\={"size": 35}, loc\="center") plt.xlabel("Betweenness Centrality", fontdict\={"size": 20}) plt.ylabel("Counts", fontdict\={"size": 20}) Text(0, 0.5, 'Counts') ![../../_images/c1774512a7735c2962bbd8d40b6a04db17722c223e339bb4de6d643899e1f200.png](../../_images/c1774512a7735c2962bbd8d40b6a04db17722c223e339bb4de6d643899e1f200.png) As we can see, the vast majority of betweenness centralities is below \\(0.01\\). That makes sense as the graph is very sparse and thus most nodes do not act as bridges in shortest paths. However, that also results in some nodes having extremely high betweenness centralities as for example node \\(107\\) with \\(0.48\\) and node \\(1684\\) with \\(0.34\\) betweenness centrality. We can also get an image on the nodes with the highest betweenness centralities and where they are located in the network. It is clear that they are the bridges from one community to another: node\_size \= \[\ v \* 1200 for v in betweenness\_centrality.values()\ \] \# set up nodes size for a nice graph representation plt.figure(figsize\=(15, 8)) nx.draw\_networkx(G, pos\=pos, node\_size\=node\_size, with\_labels\=False, width\=0.15) plt.axis("off") (np.float64(-0.9991946166753769), np.float64(1.1078343337774277), np.float64(-1.1645995157957079), np.float64(0.7322139519453049)) ![../../_images/b508cfe48986a2563ed6a0d28e6895aa0e6e1bace489c5e6939d7dc353e7aed5.png](../../_images/b508cfe48986a2563ed6a0d28e6895aa0e6e1bace489c5e6939d7dc353e7aed5.png) ### Closeness Centrality[#](#closeness-centrality "Link to this heading") Closeness centrality scores each node based on their ‘closeness’ to all other nodes in the network. For a node \\(v\\), its closeness centrality measures the average farness to all other nodes. In other words, the higher the closeness centrality of \\(v\\), the closer it is located to the center of the network. The closeness centrality measure is very important for the monitoring of the spread of false information (e.g. fake news) or viruses (e.g. malicious links that gain control of the facebook account in this case). Let’s examine the example of fake news. If the user with the highest closeness centrality measure started spreading some fake news information (sharing or creating a post), the whole network would get missinformed the quickest possible. However, if a user with very low closeness centrality would try the same, the spread of the missinformation to the whole network would be much slower. That is because the false information would have to firstly reach a user with high closeness centrality that would spread it to many different parts of the network. * The nodes with the highest closeness centralities will be found now: closeness\_centrality \= nx.centrality.closeness\_centrality( G ) \# save results in a variable to use again (sorted(closeness\_centrality.items(), key\=lambda item: item\[1\], reverse\=True))\[:8\] \[(107, 0.45969945355191255),\ (58, 0.3974018305284913),\ (428, 0.3948371956585509),\ (563, 0.3939127889961955),\ (1684, 0.39360561458231796),\ (171, 0.37049270575282134),\ (348, 0.36991572004397216),\ (483, 0.3698479575013739)\] Inspecting the users with the highest closeness centralities, we understand that there is not a huge gap between them in contrast to the previous metrics. Also, the nodes \\(107, 1684, 348\\) are the only `spotlight nodes` found in the ones with the highest closeness centralities. That means that a node that has many friends is not necessary close to the center of the network. Also, the average distance of a particular node \\(v\\) to any other node can be found easily with the formula: \\\[\\frac{1}{closeness\\,centrality(v)}\\\] 1 / closeness\_centrality\[107\] 2.1753343239227343 The distance from node \\(107\\) to a random node is around two hops Furthermore, the distribution of the closeness centralities: plt.figure(figsize\=(15, 8)) plt.hist(closeness\_centrality.values(), bins\=60) plt.title("Closeness Centrality Histogram ", fontdict\={"size": 35}, loc\="center") plt.xlabel("Closeness Centrality", fontdict\={"size": 20}) plt.ylabel("Counts", fontdict\={"size": 20}) Text(0, 0.5, 'Counts') ![../../_images/54c678ffcef3e6e75b45e9db7212ed2a1c06b9a98b1206b8ef575937cbfc68a5.png](../../_images/54c678ffcef3e6e75b45e9db7212ed2a1c06b9a98b1206b8ef575937cbfc68a5.png) The closeness centralities are distributed over various values from \\(0.17\\) to \\(0.46\\). In fact, the majority of them are found between \\(0.25\\) and \\(0.3\\). That means that the majority of nodes are relatively close to the center of the network and thus close to other nodes in general. However, there are some communities that are located further away, whose nodes would have the minimum closeness centralities, as seen below: node\_size \= \[\ v \* 50 for v in closeness\_centrality.values()\ \] \# set up nodes size for a nice graph representation plt.figure(figsize\=(15, 8)) nx.draw\_networkx(G, pos\=pos, node\_size\=node\_size, with\_labels\=False, width\=0.15) plt.axis("off") (np.float64(-0.9991946166753769), np.float64(1.1078343337774277), np.float64(-1.1645995157957079), np.float64(0.7322139519453049)) ![../../_images/2e8134242b765899d47c3076122360931af966e2b491f39d1d55bf1a562b520a.png](../../_images/2e8134242b765899d47c3076122360931af966e2b491f39d1d55bf1a562b520a.png) ### Eigenvector Centrality[#](#eigenvector-centrality "Link to this heading") Eigenvector centrality is the metric to show how connected a node is to other important nodes in the network. It measures a node’s influence based on how well it is connected inside the network and how many links its connections have and so on. This measure can identify the nodes with the most influence over the whole network. A high eigenvector centrality means that the node is connected to other nodes who themselves have high eigenvector centralities. In this facebook analysis, the measure is associated with the users ability to influence the whole graph and thus the users with the highest eigenvector centralities are the most important nodes in this network. * The nodes with the highest eigenvector centralities will be examined now: eigenvector\_centrality \= nx.centrality.eigenvector\_centrality( G ) \# save results in a variable to use again (sorted(eigenvector\_centrality.items(), key\=lambda item: item\[1\], reverse\=True))\[:10\] \[(1912, 0.09540696149067629),\ (2266, 0.08698327767886552),\ (2206, 0.08605239270584342),\ (2233, 0.08517340912756598),\ (2464, 0.08427877475676092),\ (2142, 0.08419311897991795),\ (2218, 0.0841557356805503),\ (2078, 0.08413617041724977),\ (2123, 0.08367141238206224),\ (1993, 0.0835324284081597)\] Checking the results: * Node \\(1912\\) has the highest eigenvector centrality with \\(0.095\\). This node is also a `spotlight node` and can surely be considered the most important node in this network in terms of overall influence to the whole network. In fact, this node also has some of the highest degree centralities and betweenness centralities, making the user very popular and influencious to other nodes. * Nodes \\(1993, 2078, 2206, 2123, 2142, 2218, 2233, 2266, 2464\\), even though they are not spotlight nodes, have some of the highest eigenvector centralities with around \\(0.83-0.87\\). Very interesting is the fact that all those nodes are identified for the first time, meaning they have neither the heighest degree, betweenness or closeness centralities in this graph. That leads to the conclusion that those nodes are very likely to be connected to the node \\(1912\\) and as a result have very high eigenvector centralities. Checking if those nodes are connected to the most important node \\(1912\\), the hypothesis is correct: high\_eigenvector\_centralities \= ( sorted(eigenvector\_centrality.items(), key\=lambda item: item\[1\], reverse\=True) )\[\ 1:10\ \] \# 2nd to 10th nodes with heighest eigenvector centralities high\_eigenvector\_nodes \= \[\ tuple\[0\] for tuple in high\_eigenvector\_centralities\ \] \# set list as \[2266, 2206, 2233, 2464, 2142, 2218, 2078, 2123, 1993\] neighbors\_1912 \= \[n for n in G.neighbors(1912)\] \# list with all nodes connected to 1912 all( item in neighbors\_1912 for item in high\_eigenvector\_nodes ) \# check if items in list high\_eigenvector\_nodes exist in list neighbors\_1912 True Let’s check the distribution of the eigenvector centralities: plt.figure(figsize\=(15, 8)) plt.hist(eigenvector\_centrality.values(), bins\=60) plt.xticks(ticks\=\[0, 0.01, 0.02, 0.04, 0.06, 0.08\]) \# set the x axis ticks plt.title("Eigenvector Centrality Histogram ", fontdict\={"size": 35}, loc\="center") plt.xlabel("Eigenvector Centrality", fontdict\={"size": 20}) plt.ylabel("Counts", fontdict\={"size": 20}) Text(0, 0.5, 'Counts') ![../../_images/9fbe72df71c074759ec3f4032f53f64f5615d7566ab228c2a1d987fe8b201be4.png](../../_images/9fbe72df71c074759ec3f4032f53f64f5615d7566ab228c2a1d987fe8b201be4.png) As shown in the distribution histogram, the vast majority of eigenvector centralities are below \\(0.005\\) and are actually almost \\(0\\). However, we can also see different values of eigenvector centralities as there are tiny bins all over the x axis. Now we can identify the eigenvector centralities of nodes based on their size in the following representation: node\_size \= \[\ v \* 4000 for v in eigenvector\_centrality.values()\ \] \# set up nodes size for a nice graph representation plt.figure(figsize\=(15, 8)) nx.draw\_networkx(G, pos\=pos, node\_size\=node\_size, with\_labels\=False, width\=0.15) plt.axis("off") (np.float64(-0.9991946166753769), np.float64(1.1078343337774277), np.float64(-1.1645995157957079), np.float64(0.7322139519453049)) ![../../_images/f6a0a1562d6ff938825ec281c889b10b02e3ee7b030a466c32719d67efeaf890.png](../../_images/f6a0a1562d6ff938825ec281c889b10b02e3ee7b030a466c32719d67efeaf890.png) Clustering Effects[#](#clustering-effects "Link to this heading") ------------------------------------------------------------------ The clustering coefficient of a node \\(v\\) is defined as the probability that two randomly selected friends of \\(v\\) are friends with each other. As a result, the average clustering coefficient is the average of clustering coefficients of all the nodes. The closer the average clustering coefficient is to \\(1\\), the more complete the graph will be because there’s just one giant component. Lastly, it is a sign of triadic closure because the more complete the graph is, the more triangles will usually arise. nx.average\_clustering(G) 0.6055467186200862 Now the clustering coefficient distribution will be displayed: plt.figure(figsize\=(15, 8)) plt.hist(nx.clustering(G).values(), bins\=50) plt.title("Clustering Coefficient Histogram ", fontdict\={"size": 35}, loc\="center") plt.xlabel("Clustering Coefficient", fontdict\={"size": 20}) plt.ylabel("Counts", fontdict\={"size": 20}) Text(0, 0.5, 'Counts') ![../../_images/708de3f47baf3af0f33f49e1d70c5a92398b94e4b72311214efe83d690cf3c79.png](../../_images/708de3f47baf3af0f33f49e1d70c5a92398b94e4b72311214efe83d690cf3c79.png) \\(50\\) bins were used to showcase the distribution. The bin with the highest counts concerns nodes with clustering coefficient close to \\(1\\) as there are more than two-hundred-fifty nodes in that bin. In addition, the bins of clustering coefficient between \\(0.4\\) and \\(0.8\\) contain the majority of nodes by far. The number of unique triangles in the network are found next: triangles\_per\_node \= list(nx.triangles(G).values()) sum( triangles\_per\_node ) / 3 \# divide by 3 because each triangle is counted once for each node 1612010.0 Now the average number of triangles that a node is a part of: np.mean(triangles\_per\_node) np.float64(1197.3334983906907) Due to having some nodes that belong to a great many triangles, the metric of median will give us a better understanding: np.median(triangles\_per\_node) np.float64(161.0) In fact, the median value is just \\(161\\) triangles, when the mean is around \\(1197\\) triangles that a node is part of. That means that the majority of nodes of the network belong to extremely few triangles, whereas some nodes are part of a plethora of triangles (which are extreme values that increase the mean) In conclusion, the high average clustering coefficient together with the huge number of triangles are signs of the triadic closure. In detail, the triadic closure means that as time goes on, new edges tend to form between two users that have one or more mutual friends. That can be explained by the fact that Facebook usually suggests new friends to a user when there are many mutual friends between the user and the new friend to be added. Also, there is a source of latent stress. For example, if node \\(A\\) is friends with node \\(B\\) and \\(C\\), some tension builds up if \\(B\\) and \\(C\\) are not friends with each other. Bridges[#](#bridges "Link to this heading") -------------------------------------------- First of all, an edge joining two nodes A and B in the graph is considered a bridge, if deleting the edge would cause A and B to lie in two different components. Now it is checked if there are any bridges in this network: nx.has\_bridges(G) True Actually, there are bridges in the network. Now the edges that are bridges will be saved in a list and the number of them is printed: bridges \= list(nx.bridges(G)) len(bridges) 75 The existence of so many bridges is due to the fact that this network only contains the spotlight nodes and the friends of them. As a result, some friends of spotlight nodes are only connected to a spotlight node, making that edge a bridge. Also, the edges that are local bridges are saved in a list and their number is printed. In detaill, an edge joining two nodes \\(C\\) and \\(D\\) in a graph is a local bridge, if its endpoints \\(C\\) and \\(D\\) have no friends in common. Very importantly, an edge that is a bridge is also a local bridge. Thus, this list contains all the above bridges as well: local\_bridges \= list(nx.local\_bridges(G, with\_span\=False)) len(local\_bridges) 78 Showcasing the bridges and local bridges in the network now. The bridges can be seen with the red color and the local bridges with the green color. Black edges are neither local bridges nor bridges. * It is clear that all the bridges concern nodes that are only connected to a spotlight node (have a degree of \\(1\\)) plt.figure(figsize\=(15, 8)) nx.draw\_networkx(G, pos\=pos, node\_size\=10, with\_labels\=False, width\=0.15) nx.draw\_networkx\_edges( G, pos, edgelist\=local\_bridges, width\=0.5, edge\_color\="lawngreen" ) \# green color for local bridges nx.draw\_networkx\_edges( G, pos, edgelist\=bridges, width\=0.5, edge\_color\="r" ) \# red color for bridges plt.axis("off") (np.float64(-0.9991946166753769), np.float64(1.1078343337774277), np.float64(-1.1645995157957079), np.float64(0.7322139519453049)) ![../../_images/9085be476e173f1d93717821dace91b181a5e49726b9e6009fa0a82816a9b865.png](../../_images/9085be476e173f1d93717821dace91b181a5e49726b9e6009fa0a82816a9b865.png) Assortativity[#](#assortativity "Link to this heading") -------------------------------------------------------- Assortativity describes the preference for a network’s nodes to attach to others that are similar in some way. * The assortativity in terms of nodes degrees is found with two ways: nx.degree\_assortativity\_coefficient(G) 0.06357722918564943 nx.degree\_pearson\_correlation\_coefficient( G ) \# use the potentially faster scipy.stats.pearsonr function. 0.06357722918564918 In fact, the assortativity coefficient is the Pearson correlation coefficient of degree between pairs of linked nodes. That means that it takes values from \\(-1\\) to \\(1\\). In detail, a positive assortativity coefficient indicates a correlation between nodes of similar degree, while a negative indicates correlation between nodes of different degrees. In our case the assortativity coefficient is around \\(0.064\\), which is almost 0. That means that the network is almost non-assortative, and we cannot correlate linked nodes based on their degrees. In other words, we can not draw conclusions on the number of friends of a user from his/her friends’ number of friends (friends degree). That makes sense since we only use the friends list of spotlight nodes, non spotlight nodes will tend to have much fewer friends. Network Communities[#](#network-communities "Link to this heading") -------------------------------------------------------------------- A community is a group of nodes, so that nodes inside the group are connected with many more edges than between groups. Two different algorithms will be used for communities detection in this network Firstly, a semi-synchronous label propagation method [\[1\]](#id3) is used to detect the communities. This function determines by itself the number of communities that will be detected. Now the communities will be iterated through and a colors list will be created to contain the same color for nodes that belong to the same community. Also, the number of communities is printed: colors \= \["" for x in range(G.number\_of\_nodes())\] \# initialize colors list counter \= 0 for com in nx.community.label\_propagation\_communities(G): color \= "#%06X" % randint(0, 0xFFFFFF) \# creates random RGB color counter += 1 for node in list( com ): \# fill colors list with the particular color for the community nodes colors\[node\] \= color counter 44 In detail, \\(44\\) communities were detected. Now the communities are showcased in the graph. Each community is depicted with a different color and its nodes are usually located close to each other: plt.figure(figsize\=(15, 9)) plt.axis("off") nx.draw\_networkx( G, pos\=pos, node\_size\=10, with\_labels\=False, width\=0.15, node\_color\=colors ) ![../../_images/3a471fbeb49ceedda99a290d533e4a0d4b81771994538d2e2b64a258ba6ede6a.png](../../_images/3a471fbeb49ceedda99a290d533e4a0d4b81771994538d2e2b64a258ba6ede6a.png) * Next, the asynchronous fluid communities algorithm [\[2\]](#id4) is used. With this function, we can decide the number of communities to be detected. Let’s say that \\(8\\) communities is the number we want. Again, the communities will be iterated through and a colors list will be created to contain the same color for nodes that belong to the same community. colors \= \["" for x in range(G.number\_of\_nodes())\] for com in nx.community.asyn\_fluidc(G, 8, seed\=0): color \= "#%06X" % randint(0, 0xFFFFFF) \# creates random RGB color for node in list(com): colors\[node\] \= color Now the \\(8\\) communities are shown in the graph. Again, each community is depicted with a different color: plt.figure(figsize\=(15, 9)) plt.axis("off") nx.draw\_networkx( G, pos\=pos, node\_size\=10, with\_labels\=False, width\=0.15, node\_color\=colors ) ![../../_images/25c55f91d5edc935a46aa2d8c43d7c77e48e82787a6d9a64c952786532d8122e.png](../../_images/25c55f91d5edc935a46aa2d8c43d7c77e48e82787a6d9a64c952786532d8122e.png) References[#](#references "Link to this heading") -------------------------------------------------- [Cambridge-intelligence](https://cambridge-intelligence.com/keylines-faqs-social-network-analysis/#:~:text=Centrality%20measures%20are%20a%20vital,but%20they%20all%20work%20differently.) Contents --- # NetworkX 2.8.7 — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NetworkX 2.8.7[#](#networkx-2-8-7 "Link to this heading") ========================================================== Release date: 1 October 2022 Supports Python 3.8, 3.9, and 3.10. NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. For more information, please visit our [website](https://networkx.org/) and our [gallery of examples](../auto_examples/index.html#examples-gallery) . Please send comments and questions to the [networkx-discuss mailing list](http://groups.google.com/group/networkx-discuss) . Highlights[#](#highlights "Link to this heading") -------------------------------------------------- Minor documentation and bug fixes. Merged PRs[#](#merged-prs "Link to this heading") -------------------------------------------------- * Bump release version * Fixed unused root argument in has\_bridges (#5846) * docstring updates for `union`, `disjoint_union`, and `compose` (#5892) * Updated networkx/classes/function.py . Solves Issue #5463 (#5474) * Improved documentation for all\_simple\_paths (#5944) * Change is\_path to return False when node not in G instead of raising exception (#5943) * Minor docstring touchups and test refactor for `is_path` (#5967) * Update documentation header links for latest pydata-sphinx-theme (#5966) * Fix failing example due to mpl 3.6 colorbar. (#5994) * Add Tidelift security vulnerability link (#6001) * Update linters (#6006) Improvements[#](#improvements "Link to this heading") ------------------------------------------------------ * \[[#5943](https://github.com/networkx/networkx/pull/5943)\ \] `is_path` used to raise a [`KeyError`](https://docs.python.org/3/library/exceptions.html#KeyError "(in Python v3.13)") when the `path` argument contained a node that was not in the Graph. The behavior has been updated so that `is_path` returns [`False`](https://docs.python.org/3/library/constants.html#False "(in Python v3.13)") in this case rather than raising the exception. Contributors[#](#contributors "Link to this heading") ------------------------------------------------------ * Juanita Gomez * Kevin Brown * 0ddoes * pmlpm1986 * Dan Schult * Jarrod Millman On this page --- # NetworkX 2.8.5 — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NetworkX 2.8.5[#](#networkx-2-8-5 "Link to this heading") ========================================================== Release date: 18 July 2022 Supports Python 3.8, 3.9, and 3.10. NetworkX is a Python package for the creation, manipulation, and study of the structure, dynamics, and functions of complex networks. For more information, please visit our [website](https://networkx.org/) and our [gallery of examples](../auto_examples/index.html#examples-gallery) . Please send comments and questions to the [networkx-discuss mailing list](http://groups.google.com/group/networkx-discuss) . Highlights[#](#highlights "Link to this heading") -------------------------------------------------- Minor documentation and bug fixes. Merged PRs[#](#merged-prs "Link to this heading") -------------------------------------------------- * Bump release version * Check that nodes have “pos” attribute in geometric\_edges (#5707) * Correct louvain formula, solve infinite loops (#5713) * Add more comprehensive tests for pydot (#5792) * Compute `is_strongly_connected` lazily (#5793) * Compute `is_weakly_connected` lazily (#5795) * Updated astar docstring (#5797) * Fix typo in bipartite closeness\_centrality and thought-o in tests (#5800) * Fix pydot colon check node-to-str conversion (#5809) * Temporary fix for failing tests w/ scipy1.9. (#5816) * Update distance parameter description. (#5819) * Fix #5817 (#5822) * Attempt to reverse slowdown from hasattr needed for cached\_property (#5836) * Update tests in base class and simple rename in convert.py (#5848) * Move factory attributes to the class instead of instance. (#5850) * Point to the latest URL for the description. (#5852) * Gallery example: Morse code alphabet as a prefix tree (#5867) * make lazy\_import private and remove its internal use (#5878) * Run CI against v2.8 branch * CI: add explicit path while installing pygraphviz wheels on macOS in GHA (#5805) * Deploy docs on v2.8 branch Contributors[#](#contributors "Link to this heading") ------------------------------------------------------ * Ross Barnowski * Shaked Brody * Lior * Jarrod Millman * Tomoya Nishide * Dimitrios Papageorgiou * Dan Schult * Matt Schwennesen * Mridul Seth * Matus Valo On this page --- # NXEP 4 — Default random interface — NetworkX 3.4.2 documentation [Skip to main content](#main-content) Back to top Ctrl+K * [Home Page](https://networkx.org "Home Page") * [GitHub](https://github.com/networkx/networkx "GitHub") NXEP 4 — Default random interface[#](#nxep-4-default-random-interface "Link to this heading") ============================================================================================== Author: Ross Barnowski ([rossbar@berkeley.edu](mailto:rossbar%40berkeley.edu) ) Status: Draft Type: Standards Track Created: 2022-02-24 Abstract[#](#abstract "Link to this heading") ---------------------------------------------- Pseudo-random numbers play an important role in many graph and network analysis algorithms in NetworkX. NetworkX provides a [standard interface to random number generators](../../reference/randomness.html#randomness) that includes support for [`numpy.random`](https://numpy.org/doc/stable/reference/random/index.html#module-numpy.random "(in NumPy v2.1)") and the Python built-in [`random`](https://docs.python.org/3/library/random.html#module-random "(in Python v3.13)") module. [`numpy.random`](https://numpy.org/doc/stable/reference/random/index.html#module-numpy.random "(in NumPy v2.1)") is used extensively within NetworkX and in several cases is the preferred package for random number generation. NumPy introduced a new interface in the [`numpy.random`](https://numpy.org/doc/stable/reference/random/index.html#module-numpy.random "(in NumPy v2.1)") package in NumPy version 1.17. According to [NEP19](https://numpy.org/neps/nep-0019-rng-policy.html "(in NumPy Enhancement Proposals)") , the new interface based on [`numpy.random.Generator`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator "(in NumPy v2.1)") is recommended over the legacy [`numpy.random.RandomState`](https://numpy.org/doc/stable/reference/random/legacy.html#numpy.random.RandomState "(in NumPy v2.1)") as the former has [better statistical properties](https://www.pcg-random.org/index.html) , [more features](https://numpy.org/doc/stable/reference/random/new-or-different.html "(in NumPy v2.1)") , and [improved performance](https://numpy.org/doc/stable/reference/random/performance.html "(in NumPy v2.1)") . This NXEP proposes a strategy for adopting [`numpy.random.Generator`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator "(in NumPy v2.1)") as the **default** interface for random number generation within NetworkX. Motivation and Scope[#](#motivation-and-scope "Link to this heading") ---------------------------------------------------------------------- The primary motivation for adopting [`numpy.random.Generator`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator "(in NumPy v2.1)") as the default random number generation engine in NetworkX is to allow users to benefit from the improvements in [`numpy.random.Generator`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator "(in NumPy v2.1)") , including: - Advances in statistical quality of modern pRNG’s - Improved performance - Additional features The [`numpy.random.Generator`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator "(in NumPy v2.1)") API is very similar to the [`numpy.random.RandomState`](https://numpy.org/doc/stable/reference/random/legacy.html#numpy.random.RandomState "(in NumPy v2.1)") API, so users can benefit from these improvements without any additional changes [\[1\]](#f1) to their existing NetworkX code. In principle this change would impact NetworkX users that use any of the functions decorated by [`np_random_state`](../../reference/generated/networkx.utils.decorators.np_random_state.html#networkx.utils.decorators.np_random_state "networkx.utils.decorators.np_random_state") or [`py_random_state`](../../reference/generated/networkx.utils.decorators.py_random_state.html#networkx.utils.decorators.py_random_state "networkx.utils.decorators.py_random_state") (when the `random_state` argument involves `numpy`). See the next section for details. Usage and Impact[#](#usage-and-impact "Link to this heading") -------------------------------------------------------------- In NetworkX, random number generators are typically created via a decorator: from networkx.utils import np\_random\_state @np\_random\_state("seed") \# Or could be the arg position, i.e. 0 def foo(seed\=None): return seed The decorator is responsible for mapping various different inputs into an instance of a random number generator within the function. Currently, the random number generator instance that is returned is a [`numpy.random.RandomState`](https://numpy.org/doc/stable/reference/random/legacy.html#numpy.random.RandomState "(in NumPy v2.1)") object: \>>> type(foo(None)) numpy.random.mtrand.RandomState \>>> type(foo(12345)) numpy.random.mtrand.RandomState The only way to get a [`numpy.random.Generator`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator "(in NumPy v2.1)") instance from the random state decorators is to pass the instance in directly: \>>> import numpy as np \>>> rng \= np.random.default\_rng() \>>> type(foo(rng)) numpy.random.\_generator.Generator This NXEP proposes to change the behavior so that when e.g. and integer or [`None`](https://docs.python.org/3/library/constants.html#None "(in Python v3.13)") is given for the `seed` parameter, a [`numpy.random.Generator`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator "(in NumPy v2.1)") instance is returned instead, i.e.: \>>> type(foo(None)) numpy.random.\_generator.Generator \>>> type(foo(12345)) numpy.random.\_generator.Generator [`numpy.random.RandomState`](https://numpy.org/doc/stable/reference/random/legacy.html#numpy.random.RandomState "(in NumPy v2.1)") instances can still be used as `seed`, but they must be explicitly passed in: \>>> rs \= np.random.RandomState(12345) \>>> type(foo(rs)) numpy.random.mtrand.RandomState Backward compatibility[#](#backward-compatibility "Link to this heading") -------------------------------------------------------------------------- There are three main concerns: 1. The `Generator` interface is not stream-compatible with `RandomState`, thus the results of the `Generator` methods will not be exactly the same as the corresponding `RandomState` methods. 2. There are a few slight differences in method names and availability between the `RandomState` and `Generator` APIs. 3. There is no global `Generator` instance internal to [`numpy.random`](https://numpy.org/doc/stable/reference/random/index.html#module-numpy.random "(in NumPy v2.1)") as is the case for [`numpy.random.RandomState`](https://numpy.org/doc/stable/reference/random/legacy.html#numpy.random.RandomState "(in NumPy v2.1)") . The [`numpy.random.Generator`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator "(in NumPy v2.1)") interface breaks the stream-compatibility guarantee that [`numpy.random.RandomState`](https://numpy.org/doc/stable/reference/random/legacy.html#numpy.random.RandomState "(in NumPy v2.1)") upheld of exact reproducibility of values. Switching the default random number generator from `RandomState` to `Generator` would mean functions decorated with `np_random_state` would produce different results when a value _other than an instantiated rng_ is used as the seed. For example, let’s take the following function: @np\_random\_state("seed") def bar(num, seed\=None): """Return an array of \`num\` uniform random numbers.""" return seed.random(num) With the current implementation of `np_random_state`, a user can pass in an integer value to `seed` which will be used to seed a new `RandomState` instance. Using the same seed value guarantees the output is always exactly reproducible: \>>> bar(10, seed\=12345) array(\[0.92961609, 0.31637555, 0.18391881, 0.20456028, 0.56772503,\ 0.5955447 , 0.96451452, 0.6531771 , 0.74890664, 0.65356987\]) \>>> bar(10, seed\=12345) array(\[0.92961609, 0.31637555, 0.18391881, 0.20456028, 0.56772503,\ 0.5955447 , 0.96451452, 0.6531771 , 0.74890664, 0.65356987\]) However, after changing the default rng returned by `np_random_state` to a `Generator` instance, the values produced by the decorated `bar` function for integer seeds would no longer be identical: \>>> bar(10, seed\=12345) array(\[0.22733602, 0.31675834, 0.79736546, 0.67625467, 0.39110955,\ 0.33281393, 0.59830875, 0.18673419, 0.67275604, 0.94180287\]) In order to recover exact reproducibility of the original results, a seeded `RandomState` instance would need to be explicitly created and passed in via `seed`: \>>> import numpy as np \>>> rng \= np.random.RandomState(12345) \>>> bar(10, seed\=rng) array(\[0.92961609, 0.31637555, 0.18391881, 0.20456028, 0.56772503,\ 0.5955447 , 0.96451452, 0.6531771 , 0.74890664, 0.65356987\]) Because the streams would no longer be compatible, it is proposed in this NXEP that switching the default random number generator only be considered for a major release, e.g. the transition from NetworkX 2.X to NetworkX 3.0. The second point is only a concern for users who are using [`create_random_state`](../../reference/generated/networkx.utils.misc.create_random_state.html#networkx.utils.misc.create_random_state "networkx.utils.misc.create_random_state") and the corresponding decorator [`np_random_state`](../../reference/generated/networkx.utils.decorators.np_random_state.html#networkx.utils.decorators.np_random_state "networkx.utils.decorators.np_random_state") in their own libraries. For example, the [`numpy.random.RandomState.randint`](https://numpy.org/doc/stable/reference/random/generated/numpy.random.RandomState.randint.html#numpy.random.RandomState.randint "(in NumPy v2.1)") method has been replaced by [`numpy.random.Generator.integers`](https://numpy.org/doc/stable/reference/random/generated/numpy.random.Generator.integers.html#numpy.random.Generator.integers "(in NumPy v2.1)") . Thus any code that uses `create_random_state` or `create_py_random_state` and relies on the `randint` method of the returned rng would result in an [`AttributeError`](https://docs.python.org/3/library/exceptions.html#AttributeError "(in Python v3.13)") . This can be addressed with a compatibility class similar to the `networkx.utils.misc.PythonRandomInterface` class, which provides a compatibility layer between [`random`](https://docs.python.org/3/library/random.html#module-random "(in Python v3.13)") and [`numpy.random.RandomState`](https://numpy.org/doc/stable/reference/random/legacy.html#numpy.random.RandomState "(in NumPy v2.1)") . `create_random_state` currently returns the global `numpy.random.mtrand._rand` `RandomState` instance when the input is [`None`](https://docs.python.org/3/library/constants.html#None "(in Python v3.13)") or the `numpy.random` module. By switching to [`numpy.random.Generator`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator "(in NumPy v2.1)") , this will no longer be possible as there is no global, internal `Generator` instance in the [`numpy.random`](https://numpy.org/doc/stable/reference/random/index.html#module-numpy.random "(in NumPy v2.1)") module. This should have no effect on users, as `seed=None` currently does not guarantee reproducible results. Detailed description[#](#detailed-description "Link to this heading") ---------------------------------------------------------------------- This NXEP proposes to change the default random number generator produced by the [`create_random_state`](../../reference/generated/networkx.utils.misc.create_random_state.html#networkx.utils.misc.create_random_state "networkx.utils.misc.create_random_state") function (and the related decorator [`np_random_state`](../../reference/generated/networkx.utils.decorators.np_random_state.html#networkx.utils.decorators.np_random_state "networkx.utils.decorators.np_random_state") ) from a [`numpy.random.RandomState`](https://numpy.org/doc/stable/reference/random/legacy.html#numpy.random.RandomState "(in NumPy v2.1)") instance to a [`numpy.random.Generator`](https://numpy.org/doc/stable/reference/random/generator.html#numpy.random.Generator "(in NumPy v2.1)") instance when the input to the function is either an integer or [`None`](https://docs.python.org/3/library/constants.html#None "(in Python v3.13)") . Related Work[#](#related-work "Link to this heading") ------------------------------------------------------ Scikit-learn has a similar pattern for imposing determinism on functions that depend on randomness. For example, many functions in `scikit-learn` have a `random_state` argument that functions similarly to how `seed` behaves in many NetworkX function signatures. One difference between `scikit-learn` and `networkx` is that scikit-learn **only** supports `RandomState` via the `random_state` keyword argument, whereas NetworkX implicitly supports both the built-in [`random`](https://docs.python.org/3/library/random.html#module-random "(in Python v3.13)") module, as well as both the numpy `RandomState` and `Generator` instances (depending on the type of `seed`). This is reflected in the name of the keyword argument as `random_state` (used by scikit-learn) is les ambiguous than `seed` (used by NetworkX). There are multiple relevant discussions in the scikit-learn community about potential approaches to supporting the new NumPy random interface: * [scikit-learn/scikit-learn#16988](sklearn16988) covers strategies and concerns related to enabling users to use the `Generator`\-based random number generators. * [scikit-learn/scikit-learn#14042](sklearn14042) is a higher-level discussion that includes additional information about the design considerations and constraints related to scikit-learn’s `random_state`. * There is also a related [SLEP](slep011) . Implementation[#](#implementation "Link to this heading") ---------------------------------------------------------- The implementation itself is quite simple. The logic that determines how inputs are mapped to random number generators is encapsulated in the [`create_random_state`](../../reference/generated/networkx.utils.misc.create_random_state.html#networkx.utils.misc.create_random_state "networkx.utils.misc.create_random_state") function (and the related [`create_py_random_state`](../../reference/generated/networkx.utils.misc.create_py_random_state.html#networkx.utils.misc.create_py_random_state "networkx.utils.misc.create_py_random_state") ). Currently (i.e. NetworkX <= 2.X), this function maps inputs like `None`, `numpy.random`, and integers to `RandomState` instances: def create\_random\_state(random\_state\=None): if random\_state is None or random\_state is np.random: return np.random.mtrand.\_rand if isinstance(random\_state, np.random.RandomState): return random\_state if isinstance(random\_state, int): return np.random.RandomState(random\_state) if isinstance(random\_state, np.random.Generator): return random\_state msg \= ( f"{random\_state} cannot be used to create a numpy.random.RandomState or\\n" "numpy.random.Generator instance" ) raise ValueError(msg) This NXEP proposes to modify the function to produce `Generator` instances for these inputs. An example implementation might look something like: def create\_random\_state(random\_state\=None): if random\_state is None or random\_state is np.random: return np.random.default\_rng() if isinstance(random\_state, (np.random.RandomState, np.random.Generator)): return random\_state if isinstance(random\_state, int): return np.random.default\_rng(random\_state) msg \= ( f"{random\_state} cannot be used to create a numpy.random.RandomState or\\n" "numpy.random.Generator instance" ) raise ValueError(msg) The above captures the essential change in logic, though implementation details may differ. Most of the work related implementing this change will be associated with improved/reorganized tests; including adding tests rng-stream reproducibility. Alternatives[#](#alternatives "Link to this heading") ------------------------------------------------------ The status quo, i.e. using `RandomState` by default, is a completely acceptable alternative. `RandomState` is not deprecated, and is expected to maintain its stream-compatibility guarantee in perpetuity. Another possible alternative would be to provide a package-level toggle that users could use to switch the behavior the `seed` kwarg for all functions decorated by `np_random_state` or `py_random_state`. To illustrate (ignoring implementation details): \>>> import networkx as nx \>>> from networkx.utils.misc import create\_random\_state \# NetworkX 2.X behavior: RandomState by default \>>> type(create\_random\_state(12345)) numpy.random.mtrand.RandomState \# Change random backend by setting pkg attr \>>> nx.\_random\_backend \= "Generator" \>>> type(create\_random\_state(12345)) numpy.random.\_generator.Generator Discussion[#](#discussion "Link to this heading") -------------------------------------------------- This NXEP has been discussed at several community meetings, see e.g. [these meeting notes](https://github.com/networkx/archive/blob/main/meetings/2023-03-14.md#nxep-topic-of-the-week) . The main concern that has surfaced during these discussions is that the NumPy `Generator` interface does not make the same strict stream-compatibility guarantees as the older `RandomState`. Therefore, if this NXEP were implemented as proposed, code that relies on seeded random numbers could in principle return different results with some future NumPy version due to changes in the default `BitGenerator` or `Generator` methods. Many NetworkX functions are quite sensitive to the random seed. For example, changing the seed for the default `spring_layout` function can yield a vastly different (but equally valid) layout for a network. Stream-compatibility is important for reproducibility in these contexts. Thus we have concluded through various discussions _not_ to implement the changes proposed in this NXEP. `RandomState` will remain the default random number generator for the `random_state` decorator in an effort to support strict backward compatibility for all NetworkX user code that relies on `random_state`. The `Generator` interface is _supported_ in the `random_state` decorator, and users are encouraged to use `Generator` instances in new code where stream-compatibility is not a priority. On this page ---