def __init__(self, data=None, **attr): """Initialize a graph with edges, name, or graph attributes. Parameters ---------- data : input graph Data to initialize graph. If data=None (default) an empty graph is created. The data can be an edge list, or any NetworkX graph object. If the corresponding optional Python packages are installed the data can also be a NumPy matrix or 2d ndarray, a SciPy sparse matrix, or a PyGraphviz graph. attr : keyword arguments, optional (default= no attributes) Attributes to add to graph as key=value pairs. See Also -------- convert Examples -------- >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc >>> G = nx.Graph(name='my graph') >>> e = [(1, 2), (2, 3), (3, 4)] # list of edges >>> G = nx.Graph(e) Arbitrary graph attribute pairs (key=value) may be assigned >>> G = nx.Graph(e, day="Friday") >>> G.graph {'day': 'Friday'} """ self.edge_key_dict_factory = self.edge_key_dict_factory Graph.__init__(self, data, **attr)
def add_node(self, n): if n in self: return # already in tree elif len(self.adj)==0: Graph.add_node(self,n) # first node else: # not allowed raise NetworkXError(\ "adding single node %s not allowed in non-empty tree"%(n))
def to_undirected(self, reciprocal=False): """Return an undirected representation of the digraph. Parameters ---------- reciprocal : bool (optional) If True only keep edges that appear in both directions in the original digraph. Returns ------- G : Graph An undirected graph with the same name and nodes and with edge (u,v,data) if either (u,v,data) or (v,u,data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. Notes ----- If edges in both directions (u,v) and (v,u) exist in the graph, attributes for the new undirected edge will be a combination of the attributes of the directed edges. The edge data is updated in the (arbitrary) order that the edges are encountered. For more customized control of the edge attributes use add_edge(). This returns a "deepcopy" of the edge, node, and graph attributes which attempts to completely copy all of the data and references. This is in contrast to the similar G=DiGraph(D) which returns a shallow copy of the data. See the Python copy module for more information on shallow and deep copies, http://docs.python.org/library/copy.html. Warning ------- If you have subclassed DiGraph to use dict-like objects in the data structure, those changes do not transfer to the Graph created by this method. """ H=Graph() H.name=self.name H.add_nodes_from(self) if reciprocal is True: H.add_edges_from( (u,v,deepcopy(d)) for u,nbrs in self.adjacency_iter() for v,d in nbrs.items() if v in self.pred[u]) else: H.add_edges_from( (u,v,deepcopy(d)) for u,nbrs in self.adjacency_iter() for v,d in nbrs.items() ) H.graph=deepcopy(self.graph) H.node=deepcopy(self.node) return H
def delete_node(self, n): try: if len(self.adj[n])==1: # allowed for leaf node Graph.delete_node(self,n) else: raise NetworkXError( "deleting interior node %s not allowed in tree"%(n)) except KeyError: # NetworkXError if n not in self raise NetworkXError("node %s not in graph"%n)
def delete_edge(self, u, v=None): if v is None: (u,v)=u # no v given, assume u is an edge tuple Graph.delete_edge(self,u,v) # this will always break a tree into two trees # put nodes connected to v in a new component vnodes=component.node_connected_component(self,v) for n in vnodes: self.comp[n]=self.nc self.nc+=1
def add_edge(self, u, v=None): if v is None: (u,v)=u # no v given, assume u is an edge tuple if self.has_edge(u,v): return # no parallel edges allowed elif u in self and v in self: raise NetworkXError("adding edge %s-%s not allowed in tree"%(u,v)) elif u in self or v in self: Graph.add_edge(self,u,v) return elif len(self.adj)==0: # first leaf Graph.add_edge(self,u,v) return else: raise NetworkXError("adding edge %s-%s not allowed in tree"%(u,v))
def to_undirected(self): """Return an undirected representation of the digraph. Returns ------- G : Graph An undirected graph with the same name and nodes and with edge (u,v,data) if either (u,v,data) or (v,u,data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. Notes ----- If edges in both directions (u,v) and (v,u) exist in the graph, attributes for the new undirected edge will be a combination of the attributes of the directed edges. The edge data is updated in the (arbitrary) order that the edges are encountered. For more customized control of the edge attributes use add_edge(). This is similar to Graph(self) which returns a shallow copy. self.to_undirected() returns a deepcopy of edge, node and graph attributes. """ H=Graph() H.name=self.name H.add_nodes_from(self) H.add_edges_from( (u,v,deepcopy(d)) for u,nbrs in self.adjacency_iter() for v,d in nbrs.iteritems() ) H.graph=deepcopy(self.graph) H.node=deepcopy(self.node) return H
def __init__(self,data=None,**kwds): Graph.__init__(self,**kwds) if data is not None: try: # build a graph G=Graph() G=convert.from_whatever(data,create_using=G) except: raise NetworkXError, "Data %s is not a tree"%data # check if it is a tree. if G.order()==G.size()+1 and \ component.number_connected_components(G)==1: self.adj=G.adj.copy() del G else: raise NetworkXError, "Data %s is not a tree"%data
def delete_node(self, n): # get neighbors first since this will remove all edges to them neighbors=self.neighbors(n) Graph.delete_node(self,n) # delete node and adjacent edges del self.comp[n] # remove node from component dictionary if len(neighbors)==1: return # n was a leaf node for nbr in neighbors: # make new components of each nbr and connected graph # FIXME this does more work then is necessary # since nbrs of n could be in same conected component # and then will get renumbered more than once vnodes=component.node_connected_component(self,nbr) for v in vnodes: self.comp[v]=self.nc self.nc+=1
def to_undirected(self): H = Graph() H.name = self.name H.add_nodes_from(self) H.add_edges_from((u, v, deepcopy(d)) for u, nbrs in self.adjacency_iter() for v, d in nbrs.iteritems()) H.graph = deepcopy(self.graph) H.node = deepcopy(self.node) return H
def to_undirected(self): """Return an undirected representation of the digraph. Returns ------- G : Graph An undirected graph with the same name and nodes and with edge (u,v,data) if either (u,v,data) or (v,u,data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. Notes ----- If edges in both directions (u,v) and (v,u) exist in the graph, attributes for the new undirected edge will be a combination of the attributes of the directed edges. The edge data is updated in the (arbitrary) order that the edges are encountered. For more customized control of the edge attributes use add_edge(). This returns a "deepcopy" of the edge, node, and graph attributes which attempts to completely copy all of the data and references. This is in contrast to the similar G=DiGraph(D) which returns a shallow copy of the data. See the Python copy module for more information on shallow and deep copies, http://docs.python.org/library/copy.html. """ H = Graph() H.name = self.name H.add_nodes_from(self) H.add_edges_from((u, v, deepcopy(d)) for u, nbrs in self.adjacency_iter() for v, d in nbrs.iteritems()) H.graph = deepcopy(self.graph) H.node = deepcopy(self.node) return H
def delete_edge(self, u, v=None): if v is None: (u,v)=u if self.degree(u)==1 or self.degree(v)==1: # leaf edge Graph.delete_edge(self,u,v) else: # interior edge raise NetworkXError(\ "deleting interior edge %s-%s not allowed in tree"%(u,v)) if self.degree(u)==0: # OK to delete remaining isolated node Graph.delete_node(self,u) if self.degree(v)==0: # OK to delete remaining isolated node Graph.delete_node(self,v)
def delete_edge(self, u, v=None): if v is None: (u, v) = u if self.degree(u) == 1 or self.degree(v) == 1: # leaf edge Graph.delete_edge(self, u, v) else: # interior edge raise NetworkXError(\ "deleting interior edge %s-%s not allowed in tree"%(u,v)) if self.degree(u) == 0: # OK to delete remaining isolated node Graph.delete_node(self, u) if self.degree(v) == 0: # OK to delete remaining isolated node Graph.delete_node(self, v)
def create_true_graph_copy(): ''' - <Graph>.copy() returns a true copy of the original graph - == operator for graph objects is useless, or perhaps __eq__ isn't implemented so it falls back to "is" behavior - This is NOT what I want if I don't want to copy attributes ''' g = Graph([(1, 5), (5, 5)]) g.add_node(6) g.graph['pie'] = 'apple' g.node[1]['pet'] = 'fish' g.edge[5][5]['sound'] = 'clink' h = g.copy() print(h.nodes()) # [1, 5, 6] print(h.edges()) # [(1, 5), (5, 5)] print(h.graph) # {'pie': 'apple'} print(h.node) # {1: {'pet': 'fish'}, 5: {}, 6: {}} print(h.edge) # {1: {5: {}}, 5: {1: {}, 5: {'sound': 'clink'}}, 6: {}} print(h is g) # False print(h == g) # False
def to_undirected(self): """Return an undirected representation of the digraph. A new graph is returned with the same name and nodes and with edge (u,v,data) if either (u,v,data) or (v,u,data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. """ H = Graph() H.name = self.name H.add_nodes_from(self) H.add_edges_from([(v, u, d) for (u, v, d) in self.edges_iter(data=True)]) return H
def to_undirected(self): """Return an undirected representation of the digraph. Returns ------- G : Graph An undirected graph with the same name and nodes and with edge (u,v,data) if either (u,v,data) or (v,u,data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. Notes ----- If edges in both directions (u,v) and (v,u) exist in the graph, attributes for the new undirected edge will be a combination of the attributes of the directed edges. The edge data is updated in the (arbitrary) order that the edges are encountered. For more customized control of the edge attributes use add_edge(). This returns a "deepcopy" of the edge, node, and graph attributes which attempts to completely copy all of the data and references. This is in contrast to the similar G=DiGraph(D) which returns a shallow copy of the data. See the Python copy module for more information on shallow and deep copies, http://docs.python.org/library/copy.html. """ H=Graph() H.name=self.name H.add_nodes_from(self) H.add_edges_from( (u,v,deepcopy(d)) for u,nbrs in self.adjacency_iter() for v,d in nbrs.iteritems() ) H.graph=deepcopy(self.graph) H.node=deepcopy(self.node) return H
def _check_cycle(mode_declarations): g = Graph().to_directed() for decl in mode_declarations: input_args = decl.input_arguments() output_args = decl.output_arguments() for o in output_args: g.add_node(o.name) for i in input_args: g.add_node(i.name) for o in output_args: g.add_edge(i.name, o.name) try: res = find_cycle(g) except NetworkXNoCycle: return raise CheckFailed('Cycle found: %s' % str(res))
def create_graph_from_edgeview(): ''' Fortunately, creating a graph from the EdgeView of another graph does not perform a shallow copy of the original graph - The new graph gets entirely new edges - Arbitrary attributes of the old edges are not copied - This approach will miss copying nodes who had no edges ''' g = Graph([(1, 'foo'), (1, 3)]) g.add_node(4) h = Graph(g.edges) g.edges[1, 'foo']['key'] = 'value' print(h.nodes) # [1, 'foo', 3] print(h.edges) # [(1, 'foo'), (1, 3)] print(h.edges[1, 'foo']) # {} print(g.edges[1, 'foo']) # {'key': 'value'}
def __init__(self, data=None, **kwds): Graph.__init__(self, **kwds) if data is not None: try: # build a graph G = Graph() G = convert.from_whatever(data, create_using=G) except: raise NetworkXError, "Data %s is not a tree" % data # check if it is a tree. if G.order()==G.size()+1 and \ component.number_connected_components(G)==1: self.adj = G.adj.copy() del G else: raise NetworkXError, "Data %s is not a tree" % data
def to_undirected(self): """Return an undirected representation of the digraph. A new graph is returned with the same name and nodes and with edge (u,v,data) if either (u,v,data) or (v,u,data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. """ H=Graph() H.name=self.name H.add_nodes_from(self) H.add_edges_from([(v,u,d) for (u,v,d) in self.edges_iter(data=True)]) return H
def create_graph_with_new_data(): ''' - Parallel edges are not allowed - The data can be: - An edge list - Any NetworkX graph object - The data cannot be a flat list of nodes! - It can't be a list of nodes because a bunch of unconnected nodes don't compose a very interesting graph - Nodes can be any hashable object. Recall that immutable objects are implicitly hashable: int, string, tuple, etc. ''' # Create with edge list. Since this is an undirected graph, there is only one edge between 1 and 3 g = Graph([(1, 'foo'), (1, 3), (3, 1)]) g.add_node(6) # Create with another graph print(g.nodes()) # [1, 'foo', 3, 6] print(g.edges()) # [(1, 'foo'), (1, 3)]
def make_nonmultigraph(multigraph): """ Removes duplicate edges. Instead of having multiple edges going from the same source to the same target, this function adds one edge with a weight attribute, Parameters: multigraph: The multi-graph with multi-edges Return: G: A new graph which is equivalent to the multi-graph. """ G = Graph() for node in multigraph.nodes_iter(): G.add_node(node) for edge in multigraph.edges_iter(): for existing_edge in G.edges_iter(): if existing_edge[0] == edge[0] and existing_edge[1] == edge[ 1]: #If the edge is already in the existing edge list... G.edge[edge[0]][edge[1]][ 'weight'] += 1 # the existing edge's weight is incremented G.add_edge(edge[0], edge[1], weight=1) return G
def make_nonmultigraph(multigraph): """ Removes duplicate edges. Instead of having multiple edges going from the same source to the same target, this function adds one edge with a weight attribute, Parameters: multigraph: The multi-graph with multi-edges Return: G: A new graph which is equivalent to the multi-graph. """ G = Graph() for node in multigraph.nodes_iter(): G.add_node(node) for edge in multigraph.edges_iter(): for existing_edge in G.edges_iter(): if existing_edge[0] == edge[0] and existing_edge[1] == edge[1]: #If the edge is already in the existing edge list... G.edge[edge[0]][edge[1]]['weight'] += 1 # the existing edge's weight is incremented G.add_edge(edge[0], edge[1], weight=1) return G
def get_node_attributes_(): ''' get_node_attributes(<Graph>, <attribute key>) returns a dict - The <attribute key> can be anything that could be a key (i.e. any immutable object), but in most cases it will be a string. Multiple keys cannot be specified - The returned dict's keys are node identifiers who have the desired attribute key ''' g = Graph([(1, 5), (5, 5)]) g.node[5]['foo'] = 'bar' g.node[1]['foo'] = 'boo' # Works as expected #d = function.get_node_attributes(g, 'foo') #print(type(d)) # <class 'dict'> #print(len(d)) # 2 #print(d) # {1: 'boo', 5: 'bar'} # Does not work. There is no object with the literal attribute key ('foo', 'hi') g.node[1]['hi'] = 'bye' d = function.get_node_attributes(g, ('foo', 'hi')) print(d) # {} g.node[1][('foo', 'hi')] = 'lmao' print(function.get_node_attributes(g, ('foo', 'hi'))) # {1: 'lmao'}
def add_edge(self, u, v=None): if v is None: (u,v)=u # no v given, assume u is an edge tuple if self.has_edge(u,v): # no parallel edges return elif u in self and v in self: raise NetworkXError, "adding edge %s-%s not allowed in tree"%(u,v) elif u in self: Graph.add_edge(self,u,v) self.par[v]=u return elif v in self: Graph.add_edge(self,u,v) self.par[u]=v return elif len(self.adj)==0: # first leaf Graph.add_edge(self,u,v) self.par[v]=u # u is v's parent return else: raise NetworkXError, "adding edge %s-%s not allowed in tree"%(u,v)
def add_edge(self, u, v=None): if v is None: (u, v) = u # no v given, assume u is an edge tuple if self.has_edge(u, v): return # no parallel edges if u in self: # u is in forest if v in self: # v is in forest if self.comp[u] == self.comp[v]: # same tree? raise NetworkXError, \ "adding edge %s-%s not allowed in forest"%(u,v) else: # join two trees Graph.add_edge(self, u, v) ucomp = self.comp[u] # set component number of v tree to u tree for n in component.node_connected_component(self, v): self.comp[n] = ucomp else: # add u-v to tree in component with u Graph.add_edge(self, u, v) self.comp[v] = self.comp[u] else: # make new tree with only u-v Graph.add_edge(self, u, v) self.comp[u] = self.nc self.comp[v] = self.nc self.nc += 1
def add_edge(self, u, v=None): if v is None: (u,v)=u # no v given, assume u is an edge tuple if self.has_edge(u,v): return # no parallel edges if u in self: # u is in forest if v in self: # v is in forest if self.comp[u]==self.comp[v]: # same tree? raise NetworkXError, \ "adding edge %s-%s not allowed in forest"%(u,v) else: # join two trees Graph.add_edge(self,u,v) ucomp=self.comp[u] # set component number of v tree to u tree for n in component.node_connected_component(self,v): self.comp[n]=ucomp else: # add u-v to tree in component with u Graph.add_edge(self,u,v) self.comp[v]=self.comp[u] else: # make new tree with only u-v Graph.add_edge(self,u,v) self.comp[u]=self.nc self.comp[v]=self.nc self.nc+=1
def add_edge(self, u, v=None): if v is None: (u, v) = u # no v given, assume u is an edge tuple if self.has_edge(u, v): # no parallel edges return elif u in self and v in self: raise NetworkXError, "adding edge %s-%s not allowed in tree" % (u, v) elif u in self: Graph.add_edge(self, u, v) self.par[v] = u return elif v in self: Graph.add_edge(self, u, v) self.par[u] = v return elif len(self.adj) == 0: # first leaf Graph.add_edge(self, u, v) self.par[v] = u # u is v's parent return else: raise NetworkXError, "adding edge %s-%s not allowed in tree" % (u, v)
def neighbors_(): '''Functional equivalent to <Graph>.neighbors(<v>)''' g = Graph([(1, 2), (2, 3)]) print(function.neighbors(g, 2)) # [1, 3]
def to_undirected(self, reciprocal=False, as_view=False): """Returns an undirected representation of the digraph. Parameters ---------- reciprocal : bool (optional) If True only keep edges that appear in both directions in the original digraph. as_view : bool (optional, default=False) If True return an undirected view of the original directed graph. Returns ------- G : Graph An undirected graph with the same name and nodes and with edge (u, v, data) if either (u, v, data) or (v, u, data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. See Also -------- Graph, copy, add_edge, add_edges_from Notes ----- If edges in both directions (u, v) and (v, u) exist in the graph, attributes for the new undirected edge will be a combination of the attributes of the directed edges. The edge data is updated in the (arbitrary) order that the edges are encountered. For more customized control of the edge attributes use add_edge(). This returns a "deepcopy" of the edge, node, and graph attributes which attempts to completely copy all of the data and references. This is in contrast to the similar G=DiGraph(D) which returns a shallow copy of the data. See the Python copy module for more information on shallow and deep copies, https://docs.python.org/2/library/copy.html. Warning: If you have subclassed DiGraph to use dict-like objects in the data structure, those changes do not transfer to the Graph created by this method. Examples -------- >>> G = nx.path_graph(2) # or MultiGraph, etc >>> H = G.to_directed() >>> list(H.edges) [(0, 1), (1, 0)] >>> G2 = H.to_undirected() >>> list(G2.edges) [(0, 1)] """ graph_class = self.to_undirected_class() if as_view is True: return nx.graphviews.generic_graph_view(self, Graph) # deepcopy when not a view G = Graph() G.graph.update(deepcopy(self.graph)) G.add_nodes_from((n, deepcopy(d)) for n, d in self._node.items()) if reciprocal is True: G.add_edges_from((u, v, deepcopy(d)) for u, nbrs in self._adj.items() for v, d in nbrs.items() if v in self._pred[u]) else: G.add_edges_from((u, v, deepcopy(d)) for u, nbrs in self._adj.items() for v, d in nbrs.items()) return G
def __init__(self, incoming_graph_data=None, multigraph_input=None, **attr): """Initialize a graph with edges, name, or graph attributes. Parameters ---------- incoming_graph_data : input graph Data to initialize graph. If incoming_graph_data=None (default) an empty graph is created. The data can be an edge list, or any NetworkX graph object. If the corresponding optional Python packages are installed the data can also be a NumPy matrix or 2d ndarray, a SciPy sparse matrix, or a PyGraphviz graph. multigraph_input : bool or None (default None) Note: Only used when `incoming_graph_data` is a dict. If True, `incoming_graph_data` is assumed to be a dict-of-dict-of-dict-of-dict structure keyed by node to neighbor to edge keys to edge data for multi-edges. A NetworkXError is raised if this is not the case. If False, :func:`to_networkx_graph` is used to try to determine the dict's graph data structure as either a dict-of-dict-of-dict keyed by node to neighbor to edge data, or a dict-of-iterable keyed by node to neighbors. If None, the treatment for True is tried, but if it fails, the treatment for False is tried. attr : keyword arguments, optional (default= no attributes) Attributes to add to graph as key=value pairs. See Also -------- convert Examples -------- >>> G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc >>> G = nx.Graph(name="my graph") >>> e = [(1, 2), (2, 3), (3, 4)] # list of edges >>> G = nx.Graph(e) Arbitrary graph attribute pairs (key=value) may be assigned >>> G = nx.Graph(e, day="Friday") >>> G.graph {'day': 'Friday'} """ self.edge_key_dict_factory = self.edge_key_dict_factory # multigraph_input can be None/True/False. So check "is not False" if isinstance(incoming_graph_data, dict) and multigraph_input is not False: Graph.__init__(self) try: convert.from_dict_of_dicts(incoming_graph_data, create_using=self, multigraph_input=True) self.graph.update(attr) except Exception as err: if multigraph_input is True: raise nx.NetworkXError( f"converting multigraph_input raised:\n{type(err)}: {err}" ) Graph.__init__(self, incoming_graph_data, **attr) else: Graph.__init__(self, incoming_graph_data, **attr)
def add_node(self, n): Graph.add_node(self,n) # this is not called from add_edge so we must assign # and component (else that is assigned in add_edge) self.comp[n]=self.nc self.nc+=1
def to_undirected(self, reciprocal=False): """Return an undirected representation of the digraph. Parameters ---------- reciprocal : bool (optional) If True only keep edges that appear in both directions in the original digraph. Returns ------- G : Graph An undirected graph with the same name and nodes and with edge (u,v,data) if either (u,v,data) or (v,u,data) is in the digraph. If both edges exist in digraph and their edge data is different, only one edge is created with an arbitrary choice of which edge data to use. You must check and correct for this manually if desired. Notes ----- If edges in both directions (u,v) and (v,u) exist in the graph, attributes for the new undirected edge will be a combination of the attributes of the directed edges. The edge data is updated in the (arbitrary) order that the edges are encountered. For more customized control of the edge attributes use add_edge(). This returns a "deepcopy" of the edge, node, and graph attributes which attempts to completely copy all of the data and references. This is in contrast to the similar G=DiGraph(D) which returns a shallow copy of the data. See the Python copy module for more information on shallow and deep copies, http://docs.python.org/library/copy.html. Warning ------- If you have subclassed DiGraph to use dict-like objects in the data structure, those changes do not transfer to the Graph created by this method. """ H = Graph() H.name = self.name H.add_nodes_from(self) if reciprocal is True: H.add_edges_from((u, v, deepcopy(d)) for u, nbrs in self.adjacency_iter() for v, d in nbrs.items() if v in self.pred[u]) else: H.add_edges_from((u, v, deepcopy(d)) for u, nbrs in self.adjacency_iter() for v, d in nbrs.items()) H.graph = deepcopy(self.graph) H.node = deepcopy(self.node) return H
def __init__(self, data=None, **attr): self.edge_key_dict_factory = self.edge_key_dict_factory Graph.__init__(self, data, **attr)
def get_neighbors(): '''Get a Python list of neighbors connected to <v> via <Graph>.neighbors(<v>)''' g = Graph([(1, 2), (2, 3)]) n = g.neighbors(2) print(type(n)) # <class 'list'> print(n) # [1, 3]
def create_empty_graph(): '''Create an empty graph with no nodes or edges''' g = Graph() print(type(g)) # <class 'networkx.classes.graph.Graph'>
def create_graph_from_edges(): ''' - Don't use this strategy alone to copy a graph - None of the arbitrary attributes from nodes, edges, or the graph are copied - When a new graph is created from the edges of an existing graph, the nodes that form each edge are also created - Thus, creating a copy from edges is almost a true copy - It is NOT a true copy because any nodes without edges are not copied! ''' g = Graph([(1, 5), (5, 5)]) g.add_node(6) g.edge[1][5]['foo'] = 'bar' print(g.edge[1][5]) # {'foo': 'bar'} print(g.nodes()) # [1, 5, 6] h = Graph() # Yes, this is the required syntax to do this h.add_edges_from(g.edges()) print(h.edge[1][5]) # {} print(h.nodes()) # [1, 5] print(h.edges()) # [(1, 5), (5, 5)]
def add_node(self, n): Graph.add_node(self, n) # this is not called from add_edge so we must assign # and component (else that is assigned in add_edge) self.comp[n] = self.nc self.nc += 1
def to_subgraph(self, begin, end, multigraph=False, edge_data=False, edge_interval_data=False, node_data=False): """Return a networkx Graph or MultiGraph which includes all the nodes and edges which have overlapping intervals with the given interval. Parameters ---------- begin: integer Inclusive beginning time of the edge appearing in the interval graph. Must be bigger than begin. end: integer Non-inclusive ending time of the edge appearing in the interval graph. multigraph: bool, optional (default= False) If True, a networkx MultiGraph will be returned. If False, networkx Graph. edge_data: bool, optional (default= False) If True, edges will keep their attributes. edge_interval_data: bool, optional (default= False) If True, each edge's attribute will also include its begin and end interval data. If `edge_data= True` and there already exist edge attributes with names begin and end, they will be overwritten. node_data : bool, optional (default= False) if True, each node's attributes will be included. See Also -------- to_snapshots : divide the interval graph to snapshots Notes ----- If multigraph= False, and edge_data=True or edge_interval_data=True, in case there are multiple edges, only one will show with one of the edge's attributes. Note: nodes with no edges will not appear in any subgraph. Examples -------- >>> G = dnx.IntervalGraph() >>> G.add_edges_from([(1, 2, 3, 10), (2, 4, 1, 11), (6, 4, 12, 19), (2, 4, 8, 15)]) >>> H = G.to_subgraph(4, 12) >>> type(H) <class 'networkx.classes.graph.Graph'> >>> list(H.edges(data=True)) [(1, 2, {}), (2, 4, {})] >>> H = G.to_subgraph(4, 12, edge_interval_data=True) >>> type(H) <class 'networkx.classes.graph.Graph'> >>> list(H.edges(data=True)) [(1, 2, {'end': 10, 'begin': 3}), (2, 4, {'end': 15, 'begin': 8})] >>> M = G.to_subgraph(4, 12, multigraph=True, edge_interval_data=True) >>> type(M) <class 'networkx.classes.multigraph.MultiGraph'> >>> list(M.edges(data=True)) [(1, 2, {'end': 10, 'begin': 3}), (2, 4, {'end': 11, 'begin': 1}), (2, 4, {'end': 15, 'begin': 8})] """ if end <= begin: raise NetworkXError( "IntervalGraph: subgraph duration must be strictly bigger than zero: " "begin: {}, end: {}.".format(begin, end)) iedges = self.tree[begin:end] if multigraph: G = MultiGraph() else: G = Graph() if edge_data and edge_interval_data: G.add_edges_from((iedge.data[0], iedge.data[1], dict(self._adj[iedge.data[0]][iedge], begin=iedge.begin, end=iedge.end)) for iedge in iedges) elif edge_data: G.add_edges_from((iedge.data[0], iedge.data[1], self._adj[iedge.data[0]][iedge].copy()) for iedge in iedges) elif edge_interval_data: G.add_edges_from((iedge.data[0], iedge.data[1], { 'begin': iedge.begin, 'end': iedge.end }) for iedge in iedges) else: G.add_edges_from( (iedge.data[0], iedge.data[1]) for iedge in iedges) # include node attributes if node_data: G.add_nodes_from((n, self._node[n].copy()) for n in G.nodes) return G
def __init__(self): super().__init__() self._table = {self.url: self.url} self._graph = Graph()
def create_graph_from_nodes(): ''' - Don't use this strategy alone to copy a graph - None of the arbitrary attributes from nodes, edges, or the graph are copied - If the nodes of a graph object are used to create a new graph object: - No edges are created in the new graph. ''' g = Graph([(1, 5), (5, 5)]) g.graph['baz'] = 'boo' g.add_node(6) print(g.nodes()) # [1, 5, 6] print(g.edges()) # [(1, 5), (5, 5)] g.node[5]['foo'] = 'bar' print(g.node[5]) # {'foo': 'bar'} h = Graph() h.add_nodes_from(g) print(h.graph) # {} print(h.nodes()) # [1, 5, 6] print(h.edges()) # {} print(h.node[5]) # {}
def get_edge_attributes_(): g = Graph([(1, 5), (5, 5)]) g.edge[5][1]['foo'] = 'bar' print(function.get_edge_attributes(g, 'foo')) # {(1, 5): 'bar'}
def bad_create_graph(): '''NetworkX does not view a flat list as a list of edges''' g = Graph([ 1, 2 ]) # networkx.exception.NetworkXError: Input is not a valid edge list
def get_nodes_and_data(): ''' The <Graph>.nodes() method accepts an optional kwarg "data" that, regardless of value, is interpreted as a truthy or falsy value - If truthy, a list of 2-tuples is returned. Each 2-tuple consists of (<key>, <attr dict>) - If falsy, a list of keys is returned In v1.11 that's all that happens. It's very simple ''' g = Graph() g.add_nodes_from(['a', 'b'], data='quack') g.add_node('c', data=False) g.add_node('d') print(g.nodes()) # ['a', 'b', 'c', 'd'] print(g.nodes(data=False)) # ['a', 'b', 'c', 'd'] print( g.nodes(data=True) ) # [('a', {'data': 'quack'}), ('b', {'data': 'quack'}), ('c', {'data': False}), ('d', {})] print( g.nodes(data='no') ) # [('a', {'data': 'quack'}), ('b', {'data': 'quack'}), ('c', {'data': False}), ('d', {})]
def __init__(self, oldCG=None): """ """ Graph.__init__(self, oldCG) self.matrix = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
phe2 = pd.read_table(phe2_file,index_col=0,sep=",") phe3 = pd.read_table(phe3_file,index_col=0,sep=",") phe1.columns = [i for i in range(0, phe1.shape[1])] phe2.columns = [i for i in range(0, phe2.shape[1])] phe3.columns = [i for i in range(0, phe3.shape[1])] curr_path = os.getcwd() + '/' windowGraph = {} # output undirected graph # for i in range(0, columns_num): # tree_statis(weight_value, i) s = 0 for window in range(0, columns_num): windowGraph[window] = Graph() df = data[data[data.columns[window]] >= (weight_value + 0.00001)] # print window, weight_value, df.shape for edge in range(0, df.shape[0]): node_1, node_2 = df.index[edge].split('-') windowGraph[window].add_edge(node_1, node_2) # 先产生第一个window的 tree // First generate the first window of the tree # print windowGraph[0].number_of_nodes(), windowGraph[0].number_of_edges() cliqueGraph0, dic_term0, dic_term_num0, term = tree0(weight_value, 0, term) dic_all = {} dic_all = dic_term0.copy() dic_all_term_num = dic_term_num0.copy() copy_clique = cliqueGraph0 for i in range(1, columns_num): print 'begin term num:', term
def examine_nonexistent_node_attributes(): '''Results are identical to v1.11. There is no magical nonexistent item handling by a NodeView''' g = Graph([(1, 5), (5, 5)]) g.nodes.get(6, {})['foo'] = 'bar' #print(g.nodes[6]) # KeyError print(g.nodes) # [1, 5]