NetworkX graphviz_layout not working? - python

I encountered a problem when trying to plot a graph with many nodes using NetworkX and graphviz_layout. More specifically, the arguments that pass into nx.graphviz_layout do not help at all. Attached is the code I use:
G=some_graph()
import matplotlib.pyplot as plt
plt.figure(figsize=(32,32))
# use graphviz to find radial layout
pos=nx.graphviz_layout(G,prog="dot",
root=1000,
args='-splines=true -nodesep=0.6 -overlap=scalexy'
)
nx.draw(G,pos,
with_labels=True,
alpha=0.5,
node_size=600,
font_size=10
)
plt.savefig("imagenet_layout.png")
No matter how I change "args" in nx.graphviz_layout, the output image would be the same, and all nodes overlap with each other. Could anybody help me with this? Thanks!

For me it seems that in order to give args to the prog you need to use the format '-G' +'argsname=x'. I noticed in the example they give the docs the arg epsilon asG.draw(‘test.ps’,prog=’twopi’,args=’-Gepsilon=1’). So I tried out that pattern as shown below. I just added G in front of the arguments. Now, these arguments vary quite a bit depending on what prog you use, so you definitely want to use 'dot' for what you want to accomplish. You can see all the possible arguments and how they work with each prog here. For my porpoises, I needed to have the nodesep=0.01.
G=some_graph()
import matplotlib.pyplot as plt
plt.figure(figsize=(32,32))
# use graphviz to find radial layout
pos=nx.graphviz_layout(G,prog="dot",
root=1000,
args='-Gsplines=true -Gnodesep=0.6 -Goverlap=scalexy'
)
nx.draw(G,pos,
with_labels=True,
alpha=0.5,
node_size=600,
font_size=10
)
plt.savefig("imagenet_layout.png")
Here is a comparison of my graph with and without the args, with code. First without the args.
A = nx.nx_agraph.to_agraph(G) # convert to a graphviz graph
A.layout(prog='neato') # neato layout
#A.draw('test3.pdf')
A.draw('test3.png' )
With args
A = nx.nx_agraph.to_agraph(G) # convert to a graphviz graph
A.layout(prog='dot') # neato layout
#A.draw('test3.pdf')
A.draw('test3.png',args='-Gnodesep=0.01 -Gfont_size=1', prog='dot' )
SO you can see that the images are different once I got the args to work.

My reading of the documentation for pygraphviz suggests that overlap does not work with dot.
For nodesep :
In dot, this specifies the minimum space between two adjacent nodes in the same rank, in inches.
It's not clear if the overlaps you are observing are between nodes in the same rank or between the ranks. If it is just between ranks, you may want to modify ranksep.
I do see that you are setting the positions, and then later you set the nodesize, and you are making node_size quite a bit larger than the default (600 vs 300). Since it does not know what node_size you are going to use when it finds pos, using a large enough node_size will cause overlap.
So I would recommend setting node_size to be the default, and if overlap remains, setting node_size to be smaller. If you're having issues with the between or within rank separations being out of proportion, then play with ranksep and nodesep.

About “overlap”,do you mean there are nodes drawed last time in current output? If so, add "plt.clf()"after"plt.savefig(****)"!
About the node_size, the default is 300, but the unit is not given in the document. I am using networkx these days too, can you tell me the unit if you know that?

Related

NetworkX Python Diferrent output with same input

Why everytime that a script runs shows a different structure?
Like, the logic it´s the same but it shows diferent order, is there a way to keep the same seed or structure?
Examples of same data but different results:
You can save the position of the nodes in a variable so that the network is represented always in the same way:
First create the graph:
G1 = nx.barabasi_albert_graph(20, 2)
Then run the layout function:
pos = nx.spring_layout(G1)
Then draw the graph like this:
nx.draw(G1, pos=pos)
The nx.spring_layout and other layout functions also allow for a seed value:
nx.spring_layout(G1, seed=31415)
Please note that the order of the nodes in you graph may change each time you create your graph. This may be what is affecting the layout of the graph.
Try to run each function separately.

How to fix position of nodes when using draw_circular in networkx?

I want to draw two graphs are almost same, the only difference is that the second one will have some edges grayed out. And I want nodes in the second graph stay exactly where they are in the first graph.
You need to define the optional pos argument.
In your case using circular layout pos = nx.circular_layout(G). Then you call the plotting commands like nx.draw(G, pos, other_arguments...).

Errors when drawing large Graphs in Networkx

I am trying to visualize a bipartite graph that has about 300,000 nodes total. I'm using my helper function below.
def plot_network(G):
pos = nx.spring_layout(G)
plt.figure(figsize=(10,10))
nx.draw_networkx(G, pos, iterations=20, node_grouping='bipartite',
with_labels=False, node_size = 5)
plot_network(G)
When I try to visualize the Graph in its entirety, the following errors pops up in the IPython cell and the process just hangs there forever:
C:\Users\user\AppData\Roaming\Python\Python36\site-packages\networkx\drawing\layout.py:499: RuntimeWarning:
invalid value encountered in sqrt
I tried visualizing smaller graphs by taking random samples of my data and it has worked...until the samples go above 9000 nodes.
I am not sure how to interpret the error I'm getting, but it seems graph size is a factor. So, is there a limitation on the size of graphs I can visualize in Networkx? Is there anyway I can get around this?
It seems Networkx just couldn't allocate enough space for all the nodes, try increase the figsize or shrink node_size first. If neither of those works, try upgrade the networkx package with pip install networkx --upgrade since it seems like you're not using the latest version of networkx.
In addition to Bubble Bubble's answer suggestions, try using a simpler layout algorithm. Originally I was hitting this error using spring_layout, but I found circular works.
fig, axs = plt.subplots(1,1, figsize=(25,25))
# Define node positions using layout algo
# pos = nx.spring_layout(G, center=(1,1), k=40, iterations=5) # returns error
pos = nx.circular_layout(G)
# draw
nx.draw(G,axis=axs, pos=pos, node_size=1)

NetworkX - Stop Nodes from Bunching Up - Tried Scale/K parameters

I have ~28 nodes with edges between most of them, and some being isolated (no edges). The isolated nodes are spread out nicely, but the ones which are connected are so stacked I cannot see anything. I've tried a variety of node_sizes, scale and k parameters and it always gives me (roughly) the same result. Any way to force a nicer view?
nx.draw_spring(candidateGraph, node_size = 1000, with_labels=True, scale=100, weight=weightVal, k=100)
plt.show( )
There are several ways to do this.
First a comment on how networkx draws things. Here's the documentation. It creates a dictionary pos which has the coordinates of each node. Using draw_networkx you can send the optional argument pos=my_position_dict to it.
Networkx also has commands that will define the positons for you. This way you can have more control over things.
You have several options to do what you want.
The simplest is to plot just the connected component and leave out the isolated nodes.
nodes_of_largest_component = max(nx.connected_components(G), key = len)
largest_component = G.subgraph(nodes_of_largest_component)
nx.draw_spring(largest_component)
Another would be to try one of the other (non-spring) layouts. For example:
nx.draw_spectral(G)
Alternately, you can start manipulating the positions. One way is to set a couple positions as fixed and let spring_layout handle the rest.
pre_pos = {Huck: (0,0), Christie:(0,1), Graham:(1,1), Bush: (1,2)}
my_pos = nx.spring_layout(G, pos=pre_pos, fixed = pre_pos.keys())
nx.draw_networkx(G,pos=my_pos)
Then it will hold the nodes fixed that you've specified in fixed.
Alternately, define all the positions for just the largest component. Then hold those fixed and add the other nodes. The largest component will "fill" most of the available space, and then I think spring_layout will try to keep the added nodes from being too far away (alternately once you see the layout, you can specify these by hand).
nodes_of_largest_component = max(nx.connected_components(G), key = len)
largest_component = G.subgraph(nodes_of_largest_component)
pos = nx.spring_layout(largest_component)
pos = nx.spring_layout(G,pos=pos,fixed=nodes_of_largest_component)
nx.draw_networkx(G,pos=pos)
One more thing to be aware of is that each call to spring_layout will result in a different layout. This is because it starts with some random positions. This is part of why it's useful to save the position dictionary, particularly if you plan to do anything fancy with the figure.

graph-tool fit_view and output size

Here is basic script I use for drawing:
from graph_tool.all import *
g = load_graph("data.graphml")
g.set_directed(False)
pos = sfdp_layout(g)
graph_draw(g, pos=pos, output_size=(5000, 5000), vertex_text=g.vertex_index, vertex_fill_color=g.vertex_properties["color"], edge_text=g.edge_properties["name"], output="result.png")
Main problems here are ugly edge text and vertexes that are too close to parent. As I understand this happens because by default fit_view=True and result image scaled to fit size. When I set fit_view=False result image doesn't have graph (I see only little piece).
Maybe I need another output size for fit_view=False or some additional steps?
Today I ran into the same problem.
It seems that you can use fit_view=0.9, and by using a float number yo can scale the fit. In that case it would appear 90% than the normal size. If you use 1, will be the same size.
Hope it helps.

Categories

Resources