Combine (join) networkx Graphs
The function you're looking for is compose, which produces a graph with all the edges and all the nodes that are in both graphs. If both graphs have a node with the same name, then a single copy ends up in the new graph. Similarly if the same edge exists in both. Here's an example, including edge/node attributes:
import networkx as nx
G=nx.Graph()
G.add_node(1, weight = 2)
G.add_node(2, weight = 3)
G.add_edge(1,2, flux = 5)
G.add_edge(2,4)
H=nx.Graph()
H.add_node(1, weight = 4)
H.add_edge(1,2, flux = 10)
H.add_edge(1,3)
F = nx.compose(G,H)
#F has all nodes & edges of both graphs, including attributes
#Where the attributes conflict, it uses the attributes of H.
G.nodes(data=True)
> NodeDataView({1: {'weight': 2}, 2: {'weight': 3}, 4: {}})
H.nodes(data=True)
> NodeDataView({1: {'weight': 4}, 2: {}, 3: {}})
F.nodes(data=True)
> NodeDataView({1: {'weight': 4}, 2: {'weight': 3}, 4: {}, 3: {}})
G.edges(data=True)
> EdgeDataView([(1, 2, {'flux': 5}), (2, 4, {})])
H.edges(data=True)
> EdgeDataView([(1, 2, {'flux': 10}), (1, 3, {})])
F.edges(data=True)
EdgeDataView([(1, 2, {'flux': 10}), (1, 3, {}), (2, 4, {})])
These preserve attributes, but obviously if there is a conflict this is not possible. The attributes of H
take precedence.
There are also other options to do the symmetric difference, intersection, ...
If you have multiple graphs to join together, you can use compose_all
, which just wraps a for loop around compose
.
This did it.
U=nx.Graph()
U.add_edges_from(G.edges()+H.edges())
U.add_nodes_from(G.nodes()+H.nodes()) #deals with isolated nodes
or, preserving the edge attributes:
U.add_edges_from(G.edges(data=True)+H.edges(data=True))
and, to also preserve the node attributes:
U.add_nodes_from(G.nodes(data=True)+H.nodes(data=True))