MultiGraph—Undirected graphs with self loops and parallel edges#
Overview#
 class MultiGraph(incoming_graph_data=None, multigraph_input=None, **attr)[source]#
An undirected graph class that can store multiedges.
Multiedges are multiple edges between two nodes. Each edge can hold optional data or attributes.
A MultiGraph holds undirected edges. Self loops are allowed.
Nodes can be arbitrary (hashable) Python objects with optional key/value attributes. By convention
None
is not used as a node.Edges are represented as links between nodes with optional key/value attributes, in a MultiGraph each edge has a key to distinguish between multiple edges that have the same source and destination nodes.
 Parameters:
 incoming_graph_datainput graph (optional, default: None)
Data to initialize graph. If None (default) an empty graph is created. The data can be any format that is supported by the to_networkx_graph() function, currently including edge list, dict of dicts, dict of lists, NetworkX graph, 2D NumPy array, SciPy sparse array, or PyGraphviz graph.
 multigraph_inputbool or None (default None)
Note: Only used when
incoming_graph_data
is a dict. If True,incoming_graph_data
is assumed to be a dictofdictofdictofdict structure keyed by node to neighbor to edge keys to edge data for multiedges. A NetworkXError is raised if this is not the case. If False,to_networkx_graph()
is used to try to determine the dict’s graph data structure as either a dictofdictofdict keyed by node to neighbor to edge data, or a dictofiterable keyed by node to neighbors. If None, the treatment for True is tried, but if it fails, the treatment for False is tried. attrkeyword arguments, optional (default= no attributes)
Attributes to add to graph as key=value pairs.
See also
Examples
Create an empty graph structure (a “null graph”) with no nodes and no edges.
>>> G = nx.MultiGraph()
G can be grown in several ways.
Nodes:
Add one node at a time:
>>> G.add_node(1)
Add the nodes from any container (a list, dict, set or even the lines from a file or the nodes from another graph).
>>> G.add_nodes_from([2, 3]) >>> G.add_nodes_from(range(100, 110)) >>> H = nx.path_graph(10) >>> G.add_nodes_from(H)
In addition to strings and integers any hashable Python object (except None) can represent a node, e.g. a customized node object, or even another Graph.
>>> G.add_node(H)
Edges:
G can also be grown by adding edges.
Add one edge,
>>> key = G.add_edge(1, 2)
a list of edges,
>>> keys = G.add_edges_from([(1, 2), (1, 3)])
or a collection of edges,
>>> keys = G.add_edges_from(H.edges)
If some edges connect nodes not yet in the graph, the nodes are added automatically. If an edge already exists, an additional edge is created and stored using a key to identify the edge. By default the key is the lowest unused integer.
>>> keys = G.add_edges_from([(4, 5, {"route": 28}), (4, 5, {"route": 37})]) >>> G[4] AdjacencyView({3: {0: {}}, 5: {0: {}, 1: {'route': 28}, 2: {'route': 37}}})
Attributes:
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 can be added or changed using add_edge, add_node or direct manipulation of the attribute dictionaries named graph, node and edge respectively.
>>> G = nx.MultiGraph(day="Friday") >>> G.graph {'day': 'Friday'}
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 >>> del G.nodes[1]["room"] # remove attribute >>> list(G.nodes(data=True)) [(1, {'time': '5pm'}), (3, {'time': '2pm'})]
Add edge attributes using add_edge(), add_edges_from(), subscript notation, or G.edges.
>>> key = G.add_edge(1, 2, weight=4.7) >>> keys = G.add_edges_from([(3, 4), (4, 5)], color="red") >>> keys = G.add_edges_from([(1, 2, {"color": "blue"}), (2, 3, {"weight": 8})]) >>> G[1][2][0]["weight"] = 4.7 >>> G.edges[1, 2, 0]["weight"] = 4
Warning: we protect the graph data structure by making
G.edges[1, 2, 0]
a readonly dictlike structure. However, you can assign to attributes in e.g.G.edges[1, 2, 0]
. Thus, use 2 sets of brackets to add/change data attributes:G.edges[1, 2, 0]['weight'] = 4
.Shortcuts:
Many common graph features allow python syntax to speed reporting.
>>> 1 in G # check if node in graph True >>> [n for n in G if n < 3] # iterate through nodes [1, 2] >>> len(G) # number of nodes in graph 5 >>> G[1] # adjacency dictlike view mapping neighbor > edge key > edge attributes AdjacencyView({2: {0: {'weight': 4}, 1: {'color': 'blue'}}})
Often the best way to traverse all edges of a graph is via the neighbors. The neighbors are reported as an adjacencydict
G.adj
orG.adjacency()
.>>> for n, nbrsdict in G.adjacency(): ... for nbr, keydict in nbrsdict.items(): ... for key, eattr in keydict.items(): ... if "weight" in eattr: ... # Do something useful with the edges ... pass
But the edges() method is often more convenient:
>>> for u, v, keys, weight in G.edges(data="weight", keys=True): ... if weight is not None: ... # Do something useful with the edges ... pass
Reporting:
Simple graph information is obtained using methods and objectattributes. Reporting usually provides views instead of containers to reduce memory usage. The views update as the graph is updated similarly to dictviews. The objects
nodes
,edges
andadj
provide access to data attributes via lookup (e.g.nodes[n]
,edges[u, v, k]
,adj[u][v]
) and iteration (e.g.nodes.items()
,nodes.data('color')
,nodes.data('color', default='blue')
and similarly foredges
) Views exist fornodes
,edges
,neighbors()
/adj
anddegree
.For details on these and other miscellaneous methods, see below.
Subclasses (Advanced):
The MultiGraph class uses a dictofdictofdictofdict data structure. The outer dict (node_dict) holds adjacency information keyed by node. The next dict (adjlist_dict) represents the adjacency information and holds edge_key dicts keyed by neighbor. The edge_key dict holds each edge_attr dict keyed by edge key. The inner dict (edge_attr_dict) represents the edge data and holds edge attribute values keyed by attribute names.
Each of these four dicts in the dictofdictofdictofdict structure can be replaced by a user defined dictlike object. In general, the dictlike features should be maintained but extra features can be added. To replace one of the dicts create a new graph class by changing the class(!) variable holding the factory for that dictlike structure. The variable names are node_dict_factory, node_attr_dict_factory, adjlist_inner_dict_factory, adjlist_outer_dict_factory, edge_key_dict_factory, edge_attr_dict_factory and graph_attr_dict_factory.
 node_dict_factoryfunction, (default: dict)
Factory function to be used to create the dict containing node attributes, keyed by node id. It should require no arguments and return a dictlike object
 node_attr_dict_factory: function, (default: dict)
Factory function to be used to create the node attribute dict which holds attribute values keyed by attribute name. It should require no arguments and return a dictlike object
 adjlist_outer_dict_factoryfunction, (default: dict)
Factory function to be used to create the outermost dict in the data structure that holds adjacency info keyed by node. It should require no arguments and return a dictlike object.
 adjlist_inner_dict_factoryfunction, (default: dict)
Factory function to be used to create the adjacency list dict which holds multiedge key dicts keyed by neighbor. It should require no arguments and return a dictlike object.
 edge_key_dict_factoryfunction, (default: dict)
Factory function to be used to create the edge key dict which holds edge data keyed by edge key. It should require no arguments and return a dictlike object.
 edge_attr_dict_factoryfunction, (default: dict)
Factory function to be used to create the edge attribute dict which holds attribute values keyed by attribute name. It should require no arguments and return a dictlike object.
 graph_attr_dict_factoryfunction, (default: dict)
Factory function to be used to create the graph attribute dict which holds attribute values keyed by attribute name. It should require no arguments and return a dictlike object.
Typically, if your extension doesn’t impact the data structure all methods will inherited without issue except:
to_directed/to_undirected
. By default these methods create a DiGraph/Graph class and you probably want them to create your extension of a DiGraph/Graph. To facilitate this we define two class variables that you can set in your subclass. to_directed_classcallable, (default: DiGraph or MultiDiGraph)
Class to create a new graph structure in the
to_directed
method. IfNone
, a NetworkX class (DiGraph or MultiDiGraph) is used. to_undirected_classcallable, (default: Graph or MultiGraph)
Class to create a new graph structure in the
to_undirected
method. IfNone
, a NetworkX class (Graph or MultiGraph) is used.
Subclassing Example
Create a low memory graph class that effectively disallows edge attributes by using a single attribute dict for all edges. This reduces the memory used, but you lose edge attributes.
>>> class ThinGraph(nx.Graph): ... all_edge_dict = {"weight": 1} ... ... def single_edge_dict(self): ... return self.all_edge_dict ... ... edge_attr_dict_factory = single_edge_dict >>> G = ThinGraph() >>> G.add_edge(2, 1) >>> G[2][1] {'weight': 1} >>> G.add_edge(2, 2) >>> G[2][1] is G[2][2] True
Methods#
Adding and removing nodes and edges#

Initialize a graph with edges, name, or graph attributes. 

Add a single node 

Add multiple nodes. 
Remove node n. 


Remove multiple nodes. 

Add an edge between u and v. 

Add all the edges in ebunch_to_add. 

Add weighted edges in 

Returns an unused key for edges between nodes 

Remove an edge between u and v. 

Remove all edges specified in ebunch. 

Update the graph using nodes/edges/graphs as input. 
Remove all nodes and edges from the graph. 

Remove all edges from the graph without altering nodes. 
Reporting nodes edges and neighbors#
A NodeView of the Graph as G.nodes or G.nodes(). 

Iterate over the nodes. 

Returns True if the graph contains the node n. 

Returns True if n is a node, False otherwise. 

Returns an iterator over the edges. 


Returns True if the graph has an edge between nodes u and v. 

Returns the attribute dictionary associated with edge (u, v, key). 
Returns an iterator over all neighbors of node n. 

Graph adjacency object holding the neighbors of each node. 

Returns a dict of neighbors of node n. 

Returns an iterator over (node, adjacency dict) tuples for all nodes. 


Returns an iterator over nodes contained in nbunch that are also in the graph. 
Counting nodes edges and neighbors#
Returns the number of nodes in the graph. 

Returns the number of nodes in the graph. 

Returns the number of nodes in the graph. 

A DegreeView for the Graph as G.degree or G.degree(). 


Returns the number of edges or total of all edge weights. 

Returns the number of edges between two nodes. 
Making copies and subgraphs#

Returns a copy of the graph. 

Returns an undirected copy of the graph. 

Returns a directed representation of the graph. 

Returns a SubGraph view of the subgraph induced on 

Returns the subgraph induced by the specified edges. 