I'm not sure why my network graph doesn't include edges.
I'm creating a network from a pandas dataframe that looks like the following:
I created the network as follows:
G = nx.from_pandas_edgelist(network_df,
edge_attr='weight',
source='Source',
target='Target',
create_using=nx.Graph())
but nx.draw(G) produces a graph without edges.
I tried using nx.DigGraph() but the result is the same.
Any help is greatly appreciated.
That central "blob" in your plot is a lot of nodes connected together which probably do have edges, but they are obscured by the dense mass of nodes. On the periphery there are a few nodes joined together by edges, but due to the plotting algorithm they pairs (or somewhat larger cluster) are again so close together that the nodes are obscured. The isolated nodes are isolated.
It's probably best to try another layout. The default is spring_layout. Here's another that will probably show it better:
pos = nx.circular_layout(G)
nx.draw(G, pos)
As a general rule, networkx was not designed for the purpose of graph visualization. So you may need to look at other tools like graphviz.
Related
I would like to visually group a set of nodes in networkx. Of course one could do so by changing node color, size etc. My preferred solution however should look something like the plot created with igraph below. Is this possible in networkx?
I have built a NetworkX Graph containing 50000 Nodes and about 100 Million edges. I have a list of all connected components of this group using nx.connected_components(G) method. This method results in me having clusters of nodes such that each node has a path to reach every other node in that cluster. Now what I want is, in each of these connected components, I want to find subgraphs/sub-clusters such that each of these subgraphs are connected to each other by exactly one edge. Is there a method in NetworkX that I can use directly or any other way in which I can get this done? Sorry I am very new to graph theory so need a little direction.
If I understand you correctly, then for each subgraph, you want to find all graph cuts of size 1, i.e. you want to find all edges, that if taken away partition the graph into two subgraphs. These edges are called bridges and there are efficient algorithms to find them. The implementation in networkx is accessible via networkx.algorithms.bridges.bridges.
What you want is called minimum spanning three. Using networkx you can do it like this:
import networkx as nx
import matplotlib.pyplot as plt
G = nx.Graph()
G.add_edges_from([(1,2), (1,3), (2,3), (4,5), (4,6), (5,6)])
nx.draw(nx.minimum_spanning_tree(G), with_labels=True)
plt.show()
However, I'm a little bit in doubt if networkx is able to perform on so many edges according to this benchmark. I have tested connected components algorithm on igraph, it worked for me as well (and, of course, much faster), so you might also like to look for igraph based solutions.
Result
I would like to create a networkx graph that looks more or less like this, but I haven't been able to find a way for it to display the way I need. The large nodes and edges display fine, but I haven't been able to find how to add the small nodes.
networkx.draw() has an optional argument node_size:
node_size (scalar or array, optional (default=300)) – Size of nodes. If an array is specified it must be the same length as nodelist.
If you want to draw nodes with various sizes, you should specify the array of sizes. You can also use some kind of list generator.
P.S. I don't recommend to use basic networkx drawing functional. There are many powerful visualization libraries better than networkx. Even in networkx docs you can find the same opinion. One can use Gephi, Graphviz (with various libraries) or Cytoscape for really HUGE graphs.
I have a networkx directional graph. I'd like to plot it so that nodes that interact (A->B, B->A) have two edges displayed and the colors correspond to the relative weights.
Currently I have a simple three-node graph. Naturally the flow is "order created" -> "order closed" but on not-so-rare occasions the flow can be reversed!
Since this is going on a dashboard, I need to avoid the "download it and use another software package" to visualize it. Ideally I'd just use igraph (love it in R), but it's not supported in my environment (Mode Analytics).
Is the best solution to just create a hack where I split every node to a pair: "node-sender" and "node-receiver"? At least that would have the bonus of seeing self-edges too. Or maybe switch to plotly's chord diagram?
Edit: What I'm looking for
Ideally I could just use something like the qgraph package in R.
edges <- data.frame(from = from_node, to = to_node, thickness = weights)
qgraph(edges, esize=10, gray=TRUE)
I am trying to represent graphically some graphs, and I need to group in clusters some nodes that have a common characteristics.
I am using NetworkX, and I need to do something similar with the graph from this tutorial, from the slide 44, left figure.
I want to draw some delimiting line around each cluster. My current code is like that:
vec = self.colors
colors = (linspace(0, 1, len(set(vec))) * 20 + 10)
nx.draw_circular(g, node_color=array([colors[x] for x in vec]))
show()
I wish to find an example and see how can I use networkx to cluster the graph.
I'm not positive what your question is. I think you're asking "how do I get networkx to put some nodes close together"
Before I launch into the answer, the drawing documentation for networkx is here: http://networkx.lanl.gov/reference/drawing.html
So that figure you're asking about has 4 different communities that are clustered based on having lots of edges within each community and not many outside.
If you don't want to put much effort into it, spring_layout is often good for putting tightly knit communities together. The basic algorithm of spring_layout acts as if the edges are springs (and nodes repel). So lots of edges keeps nodes close together. Note that it initializes the positions randomly, so each time you'll get a different output.
The easiest way to do this is just
nx.draw_spring(G)
But maybe you want more. If you want to, you can fix every single node's position. Define a dict, usually named pos.
pos = {}
for node in G.nodes_iter():
pos[node] = (xcoord, ycoord).
where xcoord and ycoord are the coordinates you want the node to be at.
Then just do
draw_networkx(G, pos = pos)
That's often a lot of effort. So sometimes you just tell it a few of them have to be in particular places, and let networkx do the rest
Define fixedpos for a few nodes and then run
spring_layout
telling it what nodes are fixed and giving it fixedpos as the initial positions. Then it will hold those fixed and fit everything else around.
Here is some code which generates a network that has 4 completely connected parts and a few other edges between them. (actually it generates a complete network and then deletes all but a few edges between these parts). Then it draws it with a simple spring layout. Then it fixes 4 of them to be at the corners of a square and places the other nodes around those fixed positions.
import networkx as nx
import random
import pylab as py
from math import floor
G = nx.complete_graph(20)
for edge in G.edges():
if floor(edge[0]/5.)!=floor(edge[1]/5.):
if random.random()<0.95:
G.remove_edge(edge[0],edge[1])
nx.draw_spring(G)
py.show()
fixedpos = {1:(0,0), 6:(1,1), 11:(1,0), 16:(0,1)}
pos = nx.spring_layout(G, fixed = fixedpos.keys(), pos = fixedpos)
nx.draw_networkx(G, pos=pos)
py.show()
You can also specify weights to the edges, pass the weights to spring_layout and larger weights will tell it to keep the corresponding nodes closer together. So once you've identified your communities, increase weights within the communities/clusters if necessary to keep them close together.
Note that you can also specify what color to make each node, so it is straightforward to specify the color for each community/cluster.
If you then want to draw curves around each of those clusters, you'll have to do that through matplotlib.