pip install networkx[default][default]pulls in matplotlib, scipy, pandas for drawing & I/O.import networkx as nx★The universal alias.nx.Graph()★Undirected, no parallel edges — the default.nx.DiGraph()★Directed edges (u→v).nx.MultiGraph() · nx.MultiDiGraph()Allow parallel edges between the same pair.G.to_directed() · H.to_undirected()Convert between directedness.G.is_directed() · G.is_multigraph()Ask what kind of graph you have.
G.add_node(1)★Add one node — an int, str, tuple, any hashable.G.add_nodes_from([2, 3, "x"])★Add many at once from any iterable.G.add_node(1, color="red", size=10)Attach attributes as keyword args.G.add_nodes_from([(2, {"color": "blue"})])Per-node attributes via (node, dict) tuples.G.remove_node(1)cascadesAlso deletes every edge touching it.1 in G · G.has_node(1)Membership test.
G.add_edge(1, 2)★Add an edge — auto-creates missing nodes.G.add_edges_from([(1,2), (2,3)])★Add many edges from a list of pairs.G.add_edge(1, 2, weight=4.2)★Edge attributes as kwargs.G.add_weighted_edges_from([(1,2,4.2)])Shorthand for (u, v, weight) triples.G.add_edge(1, 1)A self-loop is allowed.G.remove_edge(1, 2)Nodes stay; only the edge goes.
G.nodes[1]["color"] = "red"★Read/write a single node's attribute dict.G.edges[1, 2]["weight"]★Access an edge's attributes (same asG[1][2]).nx.set_node_attributes(G, {1: "a"}, "grp")Bulk-set from a{node: value}dict.nx.get_node_attributes(G, "grp")★Pull one attribute across all nodes → dict.nx.set_edge_attributes(G, vals, "weight")Bulk-set edge attributes.nx.get_edge_attributes(G, "weight")→{(u, v): weight}— handy for draw labels.G.graph["name"] = "demo"Graph-level attributes live onG.graph.
nx.from_pandas_edgelist(df, "src", "dst", edge_attr="w")★The most common real-world entry point.nx.from_edgelist([(1,2), (2,3)])From a plain list of pairs.nx.from_dict_of_lists({1: [2, 3]})From an adjacency dict.nx.from_numpy_array(A)From an adjacency matrix (weights from cell values).nx.from_scipy_sparse_array(S)From a SciPy sparse adjacency matrix.nx.Graph([(1,2), (2,3)])Constructors also accept edge lists directly.
G.nodes · list(G.nodes)★A live NodeView — iterate or listify.G.edges · list(G.edges)★A live EdgeView of (u, v) tuples.G.nodes(data=True) · G.edges(data=True)★Include the attribute dicts.G.number_of_nodes() · len(G)Order (node count).G.number_of_edges()= size.G.has_edge(1, 2)★Edge membership test.nx.is_empty(G) · nx.infoQuick structural summaries.
G.degree() · G.degree(1)★Degree view / one node's degree.G[1] · G.neighbors(1)★Adjacency of a node (neighbors + edge attrs).G.adj · G.adj[1]The whole dict-of-dicts adjacency structure.D.successors(1) · D.predecessors(1)★DiGraph: out-neighbors vs in-neighbors.D.in_degree() · D.out_degree()Directed degree split (plaindegree= in+out).G.degree(weight="weight")Weighted degree = sum of incident edge weights.
nx.complete_graph(5) · nx.cycle_graph(6)Classic deterministic shapes.nx.path_graph(5) · nx.star_graph(4)Line & hub-and-spoke.nx.grid_2d_graph(3, 3)A lattice; nodes are (row, col) tuples.nx.erdos_renyi_graph(100, 0.05)★Random graph — each edge present with prob p.nx.barabasi_albert_graph(100, 3)Scale-free (preferential attachment).nx.karate_club_graph()★Zachary's karate club — the "hello world" dataset.
nx.shortest_path(G, 1, 5)★Fewest-edges path (BFS) when unweighted.nx.shortest_path(G, 1, 5, weight="weight")★Min-total-weight path (Dijkstra).nx.shortest_path_length(G, 1, 5)Just the distance (hops or summed weight).nx.has_path(G, 1, 5)★Is v reachable from u?nx.all_shortest_paths(G, 1, 5)Every tied-shortest path (a generator).nx.all_pairs_shortest_path_length(G)Distances between every pair.nx.astar_path(G, 1, 5, heuristic=h)A* when you have a distance heuristic.
nx.bfs_tree(G, 0) · nx.bfs_edges(G, 0)★Breadth-first — explores in layers from the root.nx.dfs_tree(G, 0) · nx.dfs_edges(G, 0)★Depth-first — dives deep before backtracking.nx.descendants(G, 0) · nx.ancestors(G, 0)All nodes reachable to/from a node.nx.topological_sort(D)★Dependency order of a DAG (raises if cyclic).nx.dag_longest_path(D)Critical path through a DAG.
nx.is_connected(G)★Undirected: is every node reachable?nx.connected_components(G)★Generator of node sets — wrap inlist().nx.number_connected_components(G)How many disconnected pieces.G.subgraph(max(nx.connected_components(G), key=len))Extract the largest component.nx.strongly_connected_components(D)★DiGraph: mutually reachable node sets.nx.weakly_connected_components(D)Connected if you ignore edge direction.
nx.degree_centrality(G)★Share of nodes you're directly linked to.nx.betweenness_centrality(G)★How often you sit on shortest paths — the "brokers".nx.closeness_centrality(G)Inverse mean distance to everyone else.nx.eigenvector_centrality(G)Being linked to well-connected nodes.nx.pagerank(G, alpha=0.85)★The Google ranking — a random-walk score.nx.betweenness_centrality(G, k=100)ksamples pivots — approximate but fast on big graphs.
nx.clustering(G) · nx.average_clustering(G)★How often a node's neighbors are also linked.nx.transitivity(G)Global triangle density.nx.density(G)★Edges present / edges possible.nx.diameter(G) · nx.average_shortest_path_length(G)Longest / mean shortest path (needs connected).nx.is_directed_acyclic_graph(D)★DAG check before topological sort.nx.find_cycle(G) · nx.simple_cycles(D)Detect / enumerate cycles.
from networkx.algorithms import communityCommunity detection lives in its own module.community.louvain_communities(G, seed=1)★Fast modularity optimization — the go-to.community.greedy_modularity_communities(G)★Deterministic modularity clustering.community.label_propagation_communities(G)Near-linear-time label spreading.community.modularity(G, comms)Score a partition (higher = better separated).community.girvan_newman(G)Hierarchical edge-betweenness splitting.
G.subgraph([1, 2, 3])★A read-only view on a node subset.nx.ego_graph(G, 1, radius=2)A node's neighborhood out to N hops.G.copy()★An independent, mutable copy (views aren't).nx.compose(G, H) · nx.union(G, H)Merge graphs (compose = overlay shared nodes).nx.complement(G) · D.reverse()Non-edges as edges · flip all directions.nx.relabel_nodes(G, {1: "a"})Rename nodes (returns a new graph by default).
nx.draw(G, with_labels=True)★One-liner plot; thenplt.show().pos = nx.spring_layout(G, seed=42)★Force-directed positions — fix the seed for stable plots.nx.circular_layout · kamada_kawai_layout · shell_layoutOther layout algorithms →{node: (x, y)}.nx.draw(G, pos, node_color=vals, cmap=plt.cm.Blues)Colour nodes by a metric (e.g. centrality).nx.draw_networkx_edge_labels(G, pos, labels)Annotate edges (e.g. weights).nx.draw_networkx_nodes / _edges / _labelsDraw layers separately for full control.
nx.write_graphml(G, "g.graphml")★Portable XML — keeps attributes (Gephi/Cytoscape).nx.read_edgelist("g.txt") · nx.write_edgelistSimpleu v {attrs}text format.nx.read_gml · nx.read_adjlist · nx.read_pajekOther common on-disk formats.nx.node_link_data(G, edges="edges")★To a JSON-friendly dict (for D3 / web).nx.to_pandas_edgelist(G) · nx.to_pandas_adjacency(G)Back to DataFrames.nx.to_numpy_array(G) · nx.adjacency_matrix(G)Dense / sparse adjacency matrix.
nx.draw(G) → slow > ~1k nodesMatplotlib isn't for huge graphs — export to Gephi/Cytoscape.pip install nx-cugraph · nx-parallel3.xDrop-in backends that accelerate algorithms.nx.pagerank(G, backend="cugraph")Route one call to a GPU/parallel backend.NX_CUGRAPH_AUTOCONFIG=TrueEnv var to auto-dispatch supported algorithms.nx.config.backend_priorityControl which backend is tried first.G.subgraph(nodes).copy() before heavy workTrim to what you need — algorithms scale with size.