I have 1000 different names, each constituting a node. Each name can be connected with 0..1000 other names an unlimited amount of times. I would like to graph it in such a way that the distance between two nodes is inversely proportional to the number of times they are connected.
Example:
'node1' : ['node2','node2','node2','node2','node2','node3']
'node2' : ['node1','node1','node1','node1','node1']
'node3' : ['node1']
node1and node2 should huddle together and node3 should be further away.
Is that possible? Currently I'm graphing using the following code:
import networkx as nx
import matplotlib.pyplot as plt
G = nx.Graph()
G.add_nodes_from(grapharr.keys())
for k in grapharr:
for j in grapharr[k]:
G.add_edge(k,j)
nx.draw_networkx(G, **options)
grapharris a dict structure where the keys are nodes and the values are arrays containing the connections for the particular node.
It is impossible in the general case. Look at this graph:
Imagine that the central node has a thousand connections to each other, but 'square' nodes have only one connection between them. How will you draw them?
Anyway, you can set the connectivity level as edge weight and use force-directed layouts that will try to create the best layout (but not 100% optimal, of course). In networkx, there are:
spring_layout
draw_spring
graphviz_layout with prog='neato' parameter
Related
I have a graph consisting of about 200 nodes out of which I am removing nodes on each iteration.
It is possible to visualize the graph with the nodes removed, but the location of the nodes does not change while doing so. Ideally, I'd like to take away nodes and see if the remaining nodes move closer together and if clusters form as more and more nodes are removed.
I'm using networkX for this. I have tried to recompute the graph on every iteration but there seems to be some randomness in how the graph is created. I am therefore getting a very different graph on each iteration.
Is there a way to achieve what I want?
You can use draw_networkx for this:
import networkx as nx
import matplotlib.pyplot as plt
nodes = [i for i in range(10)]
edges = [(i, i+1) for i in range(5)]
G = nx.Graph()
G.add_nodes_from(nodes)
G.add_edges_from(edges)
positions = {}
for node in nodes:
positions[node] = (node, node)
nx.draw_networkx(G, pos=positions)
I generate a graph of 10 nodes with some edges, and then define a dict where the keys are the nodes (1 to 10 here) and the values are the coordinates in (x,y) format. In this example I arranged the nodes along a line.
Then, at the next iteration, just remove the nodes you do not need and pass the same dict. It will skip over the missing nodes and just plot the ones still present in the graph:
G.remove_nodes_from([5,6])
nx.draw_networkx(G, pos=positions)
You should see the nodes 5 and 6 missing.
.draw_networkx relies on matplotlib, so you can do many of the things allowed by that library. More info here.
Hope it helps!
I have a csr matrix from which I extracted data, rows, and columns.
I want to create a bipartite graph using NetworkX, and I also tried several solutions without success (as an example: Plot bipartite graph using networkx in Python). The reasons why it doesn't work, in my opinion, is a matter of labeling. My two sets and the nodes inside them have no string name.
For example in a 10x10 matrix, the rows/cols indexes represent the name of the nodes of the two sets, while the intersection of these nodes is the weighted link between those nodes.
In my case, then, if I have (0,0)=0.5 it doesn't mean that it is a self-loop; instead, the link with weight 0.5 connects the "node 0" of the first set with the "node 0" of the second one.
import networkx as nx
from networkx.algorithms import bipartite
import matplotlib.pyplot as plt
def function(foo, n_row, n_col):
n_row=10
n_col=10
After the creation of the matrix, I obtain my data
weights = weights.tocsr()
wcoo = weights.tocoo()
m_data = wcoo.data
m_rows = wcoo.row
m_cols = wcoo.col
g = nx.Graph()
# TRIAL 1
g.add_nodes_from(m_cols, bipartite=0)
g.add_nodes_from(m_rows, bipartite=1)
bi_m = bipartite.matrix.biadjacency_matrix(g, m_data)
# TRIAL 2
g.add_weighted_edges_from(zip(m_cols, m_rows, m_data))
nx.draw(g, node_size=500)
plt.show()
I expected a bipartite graph with two sets of 10 nodes per each with a certain amount of weighted links among them (without link among the same set) as a result.
I, instead, obtained a classic non-oriented graph with 10 nodes in total.
At the same time, I'd like to optimize as well as I can my code to speed-up the computational time without affecting the readability.
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... :)
As the title says, I'm using networkX to represent some cell networks in Python.
The network is at the bottom of this post since it's a large image.
The reason I'm doing this is because some of theres nodes are considered "input" and some will be considered "output", and I need to be able to calculate the number of signal paths (the number of paths from input to output) that each node participates in. however, I don't think networkX offers edge directionality, which I believe is needed to calculate signal paths for nodes.
Does anyone know if its possible to add direction to edges in networkX, or if its possible to calculate signal paths without directionality?
Here's the code I wrote up until I realized I needed directional edges:
import networkx as nx
import matplotlib.pyplot as plt
G=nx.Graph()
molecules = ["CD40L", "CD40", "NF-kB", "XBP1", "Pax5", "Bach2", "Irf4", "IL-4",
"IL-4R", "STAT6", "AID", "Blimp1", "Bcl6", "ERK", "BCR", "STAT3", "Ag", "STAT5",
"IL-21R", "IL-21", "IL-2", "IL-2R"]
Bcl6_edges = [("Bcl6", "Bcl6"), ("Bcl6", "Blimp1"), ("Bcl6", "Irf4")]
STAT5_edges = [("STAT5", "Bcl6")]
edges = Bcl6_edges + STAT5_edges
G.add_nodes_from(molecules)
G.add_edges_from(edges)
Try G = nx.DiGraph() for a directed graph.
I am trying to create a connected graph where each node has some attributes that determine what other nodes it is connected to. The network is a circular space to make it easy to establish links (there are a 1000 nodes).
The way this network works is that a node has both neighbors (the ones to its immediate left/right - i.e. node 3 has neighbors 1 and 2) and also k long distance links. The way a node picks long distance links is that it just randomly picks nodes from the clockwise direction (i.e. node 25 might have 200 as its long distance link instead of 15).
Here is a sample image of what it might looks like: http://i.imgur.com/PkYk5bz.png
Given is a symphony network but my implementation is a simplification of that.
I partially implemented this in java(via a linked list holding an arraylist) but am lost on how to do this in NetworkX. I am especially confused on how to add these specific node attributes that say that a node will find k long links but after k will not accept any more links. Is there a specific built in graph in networkx that is suited towards this model or is any graph acceptable as long as I have the correct node attributes?
It's a simplification of a more complicated network where no node leaves and no edge dissapears.
Any help or a link to an example would be appreciated on this.
This approximates to your need:
import networkx as nx
import matplotlib.pyplot as plt
import random
N = 20 # number of nodes
K = 3 # number of "long" edges
G = nx.cycle_graph(N)
for node in G.nodes():
while len(G.neighbors(node)) < K+2:
# Add K neighbors to each node
# (each node already has two neighbors from the cycle)
valid_target_found = False
while not valid_target_found:
# CAUTION
# This loop will not terminate
# if K is too high relative to N
target = random.randint(0,N-1)
# pick a random node
if (not target in G.neighbors(node)
and len(G.neighbors(target)) < K+2):
# Accept the target if (a) it is not already
# connected to source and (b) target itself
# has less than K long edges
valid_target_found = True
G.add_edge(node, target)
nx.draw_circular(G)
plt.show()
It creates the graph below. There are improvements to be made, for example, a more efficient selection of the target nodes for the long edges, but this gets you started, I hope.
In NetworkX, if there's any logic about connecting your node everything should be left to you.
Nevertheless, if you want to iterate on nodes in Python (not tested):
for (nodeId, data) in yourGraph.nodes(data=True):
// some logic here over data
// to connect your node
yourGraph.add_edge(nodeId, otherNodeId)
Side note: if you want to stay in Java you can also consider using Jung and Gephi.