how to create several regions in a networkx graph based on a criterion - networkx

I have 02 questions:
1- From the graph2 below, I want to create several regions in a networkx based on a criterion (first zone starts at node X up to a given set of nodes). For example, region 1 starts from node 1 to nodes (4 and 16). Is there a way to do that?
create regions on the graph
2- I also want to determine the depth of each node in the attached graph
node_depth of a graph
Thank you for any hint that could help.

What do you mean by "regions"? Are you asking how to create subgraphs (https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms#subgraph)? That is, do you want to create separate, smaller graphs which contain only the nodes and edges existing in the regions you have drawn in your picture?
If so, you can do that using the subgraph() function of networkx.
In your example, to create the subgraph of region 1 you would do:
region1 = graph2.subgraph([1,2,3,4,11,12,13,14,15,16])
and an equivalent statement for regions 2 and 3.
Then for node depth, I am not sure what you mean but I think you might mean distance from some root node.
Let's assume your root node is 1.
Then to find the "depth" of each node, you want to find the distance(number of edges) between that node and 1.
To do that you could do something like:
for n in myGraph.nodes():
print n, networkx.shortest_path(graph, 1, n)

I'm not an expert in networkx so sorry for not using the right terms. Coming back to my 02 points: A region can effectively be considered as a subgraph. To note that the main criterion behind the construction of the region is to start from a reference node (node 1 for region 1) and include all the nodes and edges until a specific condition is met on a specific edge (in my case it is the presence of a electric device on an edge).
how to build a region

Related

Creation of two networks with the same node coordinates

I create a network add nodes and edges. I view it (it creates a dot and pdf file automatically). Later, I want to create a second network with the same nodes but different edges. I want to place the nodes in the same coordinates, so that I can make a comparison of both graphs easily. I tried to get the coordinates of the first graph, and tried to set the coordinates of the nodes) but I couldn't find proper functions to do that. I also checked networkx package. I also tried to get a copy of the first network, and delete the edges with no success. Can someone please show me how to create a second network with the same node coordinates?
This is the simple network creation code
import graphviz as G
network1 = G.Digraph(
graph_attr={...},
node_attr={...},
edge_attr={...} )
network.node("xxx")
network.node("yyy")
network.node("zzz")
network.edge("xxx", "yyy")
network.edge("yyy", "zzz")
network1.view(file_name)
First, calculate the node positions for the first graph using the layout of your choice (say, the spring layout):
node_positions = nx.layout.spring_layout(G1)
Now, you can draw this graph and any other graph with the same nodes in the same positions:
nx.draw(G1, with_labels=True, pos=node_positions)
nx.draw(G2, with_labels=True, pos=node_positions)
Graphviz's layers feature might also be interesting:
https://graphviz.org/faq/#FaqOverlays
Here is a working example of using layers - ignore the last two lines that create a video.
https://forum.graphviz.org/t/stupid-dot-tricks-2-making-a-video/109
And here is some more background:
https://forum.graphviz.org/t/getting-layers-to-work-with-svg/107

Choosing a networkx layout that takes edge labels into account

I'm plotting networkx weighted graphs using the draw_networkx_edge_labels function. My problem is that, since edges sometimes cross each other, it is not always clear from the plot which weight belongs to which edge. For instance, in the following plot it is not immediately clear whether 2 is the weight of (1,2) or (3,7).
I'm currently using the neato layout, which does not take edge labels into account. In particular, this is how I'm drawing a weighted graph g:
layout = nx.nx_pydot.graphviz_layout(g, prog='neato')
nx.draw(g, pos=layout)
edge_labels = nx.get_edge_attributes(g, 'weight')
nx.draw_networkx_edge_labels(g, pos=layout, edge_labels=edge_labels)
I know I can manually control the position of the label along an edge using the label_pos parameter, but my question is whether there exists a way to automatically plot the graph such that edge labels do not usually collide (either using a layout that takes labels into account or a method that "neatly" selects label positions along edges).
I'm not expecting something that always works, but since my graphs are relatively sparsely connected, I hope there's a method that at least has a tendency to work well.
I have been meaning to implement this in netgraph, my fork of the networkx drawing utilities, for a while now. Unfortunately, I have a job interview on Thursday, so I won't have time to write this anytime soon. The basic idea, however, is pretty simple, and is also already implemented in some R packages such as ggrepel and also ggnetwork.
The basic idea is that you use a force directed layout to position your labels, given a predetermined and fixed layout for your nodes and edges. So:
Compute a node layout using the layout of your choice.
Partition each edge into a chain of many, many nodes, and compute the positions of the "edge nodes" using the already known positions of the source and target nodes of the edge. This partitioning is to give each edge a "mass" in the following force directed layout.
For each edge, add a "label" node and connect it to the most central "edge node".
Compute a force-directed layout keeping all nodes but the label nodes fixed (e.g. using spring_layout in networkx).
You should now have sensible edge label coordinates that do not overlap any of the edges. Use plt.annotate to plot a connection between the edge and the edge label.

SOM and the neighbour distance

In a SOM how does the neighbour distance work?
1- If two nodes are close in the map and their distance is small then they have a similar color, is that right?
2- If two nodes are close in the map but their distance is big then they have a different grey color, is that right?
3- But, what if two nodes that are totally apart have similar grey color, are they close?
4- Another question. In this map link here in some hexagons there is no country and in anoyther hexagons there is more than a country what des it mean?
The grey color is commonly used to indicate the histogram. That is, the number of hits that landed on each neuron. In that case, the color of the node is not influenced by its codebook value, but by how much data was associated with that node.
If one node has more than one label, it just means that the data points associated with those labels most closely matched the codebook value for that node.
Kohonen goes into more detail on the countries map on p. 13 of MATLAB Implementations and Applications of the Self-Organizing Map available from http://docs.unigrafia.fi/publications/kohonen_teuvo/

Additional forces to networkx spring_layout

I would like to add additional forces to networkx spring_layout.
I have a directected graph and I would like nodes to move to different sides according to the edges that they have. Nodes that have more outgoing edges should drift to nodes that have more ingoing edges should drift right. Another alternative would be. That these groups of nodes would drift towards each other, nodes with outgoing edges would get closer while nodes with ingoing edges would also get closer to each other.
I managed to look into to the source code of spring_layout of networkx http://networkx.lanl.gov/archive/networkx-0.37/networkx.drawing.layout-pysrc.html#spring_layout
but everything there is just beyond my comprehension
G.DiGraph()
G.add_edges_from([(1,5),(2,5),(3,5),(5,6),(5,7)])
The layout should show edges 1,2,3 closer to each other, the same regarding 6 and 7.
I imagine, that I could solve this by adding invisible edges via using MultiDiGraph. I could count ingoing and outgoing edges of each node and add invisible edges that connect the two groups. However, I am very sure that there are better ways of solving the problem.
Adding weights into the mix would be a good way to group things (with those invisible nodes). But the layouts have no way of knowing left from right. To get the exact layout you want you could specify each point's x,y coordinates.
import networkx as nx
G=nx.Graph()
G.add_node(1,pos=(1,1))
G.add_node(2,pos=(2,3))
G.add_node(3,pos=(3,4))
G.add_node(4,pos=(4,5))
G.add_node(5,pos=(5,6))
G.add_node(6,pos=(6,7))
G.add_node(7,pos=(7,9))
G.add_edges_from([(1,5),(2,5),(3,5),(5,6),(5,7)])
pos=nx.get_node_attributes(G,'pos')
nx.draw(G,pos)

Functions for pruning a NetworkX graph?

I am using NetworkX to generate graphs of some noisy data. I'd like to "clean up" the graph by removing branches that are spurious, and hope to avoid re-inventing the wheel.
For example, the linked picture shows a sample set of graphs, as colored nodes connected by gray lines. I'd like to prune the nodes/edges indicated by the white boxes: http://www.broadinstitute.org/~mbray/example_tree.png
Essentially, the nodes/edges to be removed are branches typically only a few nodes (< 3) in length. By removing them, I hope to have a tree with a minimum of branching but the branches that do remain are "suitably" long.
Before I start crafting code to examine subtrees for removal, are there NetworkX functions that can be used for this purpose?
You can use the betweenness_centrality score of the nodes. If the node with a low centrality score is connected to a node of remarkably higher centrality score, and has 3 edges, then you can remove the low centrality node. (the rest of the <3 connected nodes aren't connected to the main graph anymore.).
You'll need to experiment with the phrase "remarkably higher".