I would like to separate existing data of vertices and edges into two or more graphs that are not connected. I would like to give the following as example:
Imagine two hexagons on top of each other but are lying in different Z.
Hexagon 1 has the following vertices A(0,0,1), B(1,0,2), C(2,1,2), D(1,2,1), E(0,2,1), F(-1,2,1). The connectivity is as following: A-B, B-C, C-D, D-E, E-F, F-A. This part of Graph 1 as all the vertices are connected in this layer.
Hexagon2 has the following vertices A1(0,0,6), B1(1,0,7), C1(2,1,7), D1(1,2,8), E1(0,2,7), F1(-1,2,6). The connectivity is as following: A1-B1, B1-C1, C1-D1, D1-E1, E1-F1, F1-A1. This is part of Graph 2
My data is in the following form: list of Vertices and list of Edges that i can form graphs with. I would like to eliminate graph 2 and give only vertices and connectivity of graph 1 to polygon determination part of my algorithm. My real data contains around 1000 connected polygons as graph 1 and around 100 (much larger in area) polygons as graph 2. I would like to eliminate graph 2.
The problem you're describing relates to connected components.
The Python Networkx module has functions for dealing with this type of graph problems. You're looking for the connected_components function which returns all of the components, you can then pick the appropriate one (possible by number of vertices).
Related
I am new to building directed graphs with networkx and I'm trying to work out how to compare two graphs. More specifically, how to tell if a smaller graph is a subgraph (unsure of the exact terminology) of a larger graph
As an example, assume I have the following directed graph:
I would like to be able to check whether a series of smaller graphs are sub-graphs of this initial graph. Returning a True value if they are (graph B), and False if they are not (graph C):
Graph B = Sub-graph of Graph A
Graph C != Sub-graph of Graph A
Example Code
import networkx
A = nx.DiGraph()
A.add_edges_from([('A','B'),('B','C'),('C','A')])
nx.draw_networkx(A)
B = nx.DiGraph()
B.add_edges_from([('A','B')])
nx.draw_networkx(B)
C = nx.DiGraph()
C.add_edges_from([('A','B'),('A','C')])
nx.draw_networkx(C)
I've had a look through the documentation and cannot seem to find what I need. An alternative I have been considering is to represent the nodes as a sequence of strings, and then searching for each substring in the main graphs string sequence - however, I can't imagine this is the most effecient/effective/stable way to solve the problem.
You are looking for a subgraph isomorphisms.
nx.isomorphism.DiGraphMatcher(A, B).subgraph_is_isomorphic()
# True
nx.isomorphism.DiGraphMatcher(A, C).subgraph_is_isomorphic()
# False
Note that the operation can be slow for large graphs, as the problem is NP-complete.
I am trying to have nodes connect to a main node with different distances.
What I have so far:
import networkx as nx
G = nx.empty_graph( 3 , create_using= None)
G.add_edge(0,1)
G.add_edge(0,2)
Graph with equal distance to a main node
However, as it can be seen from the image, the distance between the node on either side have equal distance to the main node. Is there a way to have their distance to the main node different?
There are two parts to your question:
Part 1 - Distance between nodes:
In network theory, the distance between nodes is represented by the weight of the edge between them. So you can add all your edges with weights to your network with the following line:
G = nx.Graph()
G.add_weighted_edges_from([(0,1,4.0),(0,2,5.0)])
You can randomize the weights on the edges above for random distance between nodes.
Part 2 - Network Visualization:
I understand that you're more concerned with how the network graph is shown. If you use nx.draw_random(G) you can get randomized distances between your nodes, and suggest that you save a picture when you get the desired figure, as it randomizes every time you run.
Hope it helps... :)
In networkx, I found drawing labels of edges is very easy but I how can I draw length or relative distance of edges?
Here is my test code
G = nx.Graph()
G.add_edge(0, 1, length=1)
G.add_edge(0, 2, length=5)
pos = nx.spring_layout(G)
length = nx.get_node_attributes(G, 'length')
What I mean is the plot should show length between nodes since edge has its corresponding length. Here is example
the distance between 0 and 2 looks larger than that between 0 and 1.
Your example shows the length of each edge as a text label. That is, the text gives the length of the edge. But since most networks are not embedded in 2D, they cannot be positioned in a 2D picture that gives the right perspective for lengths as assigned to the graphs.
For example, a triangle graph can have lengths 3, 4 and 12. These cannot be realized in a length-scaled version even though it is a valid graph with valid edge lengths.
If you have an embedding of the nodes into the 2D plane (dict of nodes to 2-tuple position pairs) you can use that to draw the network as you like. But NetworkX does not provide a way to find this embedding. There is a recent Pull Request for planarity testing using NetworkX (#3040).
Aric Hagberg has some code that works with planar graphs. Take a look at this thread:
https://groups.google.com/forum/#!topic/networkx-discuss/FdhFedwvtrc
I have a network, and how to generate a random network but ensure each node retains the same degre of the original network using networkx? My first thought is to get the adjacency matrix, and perform a random in each row of the matrix, but this way is somwhat complex, e.g. need to avoid self-conneted (which is not seen in the original network) and re-label the nodes. Thanks!
I believe what you're looking for is expected_degree_graph. It generates a random graph based on a sequence of expected degrees, where each degree in the list corresponds to a node. It also even includes an option to disallow self-loops!
You can get a list of degrees using networkx.degree. Here's an example of how you would use them together in networkx 2.0+ (degree is slightly different in 1.0):
import networkx as nx
from networkx.generators.degree_seq import expected_degree_graph
N,P = 3, 0.5
G = nx.generators.random_graphs.gnp_random_graph(N, P)
G2 = expected_degree_graph([deg for (_, deg) in G.degree()], selfloops=False)
Note that you're not guaranteed to have the exact degrees for each node using expected_degree_graph; as the name implies, it's probabilistic given the expected value for each of the degrees. If you want something a little more concrete you can use configuration_model, however it does not protect against parallel edges or self-loops, so you'd need to prune those out and replace the edges yourself.
I need to compute the density of a subgraph made of vertices belonging to the same attribute "group".
ie., let g be an iGraph graph,
g.vs.select(group = 1)
gives me an object with all vertices belonging to group 1
Is there any way to compute density on the graph which is formed by these vertices and the connections between them?
In a fashion similar to this maybe?
g2.vs(g2.vs.select(group = i)).density()
Try this:
g.vs.select(group=1).subgraph().density()