Draw a weighted complex network with NetworkX - python

Can the package NetworkX be used to draw complex network with weights given by a distribution, for example a power law? Then can I write a code to draw the weight distribution or strength distribution, or even further to draw the weighted average nearest neighbours degree of a node? then coloring each class of similar degrees, or similar strenghs, etc.
I have a large data of a complex network consisting of about 300 nodes, and data about individual egdes' weights. What is the best way to draw such a network?

Edges in networkx can use the special attribute 'weight' which can be used in a number of algorithms requiring weighted edges. You can use networkx drawing commands to take these weights into account (e.g., by the spring force in a spring embedded visualisation). Something like:
>>> import networkx as nx
>>> import matplotlib.pyplot as plt
>>> G = nx.Graph()
>>> # add nodes, edges, etc.
...
>>> nx.draw_spring(G)
>>> plt.show()

Related

Link Prediction for directed graph in Python

I'm trying to predict the possible future links or missing edges in a directed graph, that is, will there be links between any node pairs in the future?
This is the dataset I'm using right now : https://github.com/JiaCheng-Lai/Link_Prediction
data_train_edge.csv is used for training data, there are about 20,000 edges. (This is a directed network, so each node pair represents a directed edge. E.g., (361, 981) represents an edge from node 361 to node 981.)
predict.csv is the node pair (node1, node2) to be predicted. The third cloumn ans is the prediction result 0 or 1. (0 means there is no hidden edge for this node pair; otherwise the ans is 1.)
import numpy as np
import pandas as pd
import networkx as nx
df = pd.read_csv("data_train_edge.csv")
G = nx.DiGraph()
G.add_edges_from(df[['node1', 'node2']].values)
I just built a directed graph with the above code, but I'm not quite sure how to do link prediction. You can use any kind of prediction method such as Jaccard Coefficient, Adamic-Adar index, etc.
However, I think networkx does not support link prediction using directed graphs because of Errors. If directed graph really doesn't works, it can be implemented with undirected graphs.
It would be a great help if can provide the code or any tips! Thanks a lot.

How to extract random subgraph with fixed number of nodes using python networkx?

I have a large graph consisting of ~80k nodes and ~2M nodes (SNAP twitter graph). I want to downsample the graph with n number of nodes picked uniformly randomly (n=~1k), without losing certain properties of the graph (average clustering coefficient and average degree).
I can subgraph in networkx using:
sg = g.subgraph(list_of_nodes)
Is it possible to use networkx to do what I mentioned?

From Adjacency matrix to Bipartite Graph in NewworkX

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.

How to generate a random network but keep the original node degree using networkx?

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.

python: using networkX on biological networks for directional edges

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.

Categories

Resources