Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What could cause NetworkX & PyGraphViz to work fine alone but not together?

I'm working to learning some Python graph visualization. I found a few blog posts doing some things I wanted to try. Unfortunately I didn't get too far, encountering this error: AttributeError: 'module' object has no attribute 'graphviz_layout'

The simplest snip of code which reproduces the error on my system is this,

In [1]: import networkx as nx
In [2]: G=nx.complete_graph(5)
In [3]: nx.draw_graphviz(G)
------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-3-481ad1c1771c> in <module>()
----> 1 nx.draw_graphviz(G)
/usr/lib/python2.7/site-packages/networkx/drawing/nx_pylab.pyc in draw_graphviz(G, prog, **kwargs)
982 See networkx.draw_networkx() for a description of optional keywords.
983 """
--> 984 pos = nx.drawing.graphviz_layout(G, prog)
985 draw(G, pos, **kwargs)
986
AttributeError: 'module' object has no attribute 'graphviz_layout'

I found a similar questions, and posts having difficulty with this combo, but not quite the same error. One was close, but it automagically resolved itself.

First, I verified all the required packages for NetworkX and PyGraphViz (which lists similar requirements to Scipy) were installed.

Next, I looked for snips to test my installation of these modules in Python. The first two examples are from the NetworkX Reference Documentation. This lists a few example snips using both MatPlotLib and GraphViz.

The MatPlotLib code example works for me (renders an image to the screen),

In [11]: import networkx as nx
In [12]: G=nx.complete_graph(5)
In [13]: import matplotlib.pyplot as plt
In [13]: nx.draw(G)
In [13]: plt.show()  

However, the GraphViz snips also produce similar errors,

In [16]: import networkx as nx
In [17]: G=nx.complete_graph(5)
In [18]: H=nx.from_agraph(A)
------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-18-808fa68cefaa> in <module>()
----> 1 H=nx.from_agraph(A)
AttributeError: 'module' object has no attribute 'from_agraph'
In [19]: A=nx.to_agraph(G)
------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-19-32d1616bb41a> in <module>()
----> 1 A=nx.to_agraph(G)
AttributeError: 'module' object has no attribute 'to_agraph'
In [20]: print G
complete_graph(5)

Then I tried PyGraphViz's tutorial page on Layout & Drawing. This has some snips as well. PyGraphViz passed with Neato (default), PyDot, and Circo Post Script output (viewed using Gimp). (The only difference is these PyGraphViz examples are not rendered to the display, but to files).

In [1]: import pygraphviz as pgv
In [2]: d={'1': {'2': None}, '2': {'1': None, '3': None}, '3': {'2': None}}
In [3]: A=pgv.AGraph(d)
In [4]: A.write("pygraphviz_test_01.dot")
In [5]: A.layout()
In [6]: A.draw('pygraphviz_test_01.png')

Adding to the complexity, PyGraphViz requires GraphViz package binaries in order to work. I'm using Arch Linux, and installed that distro's version. Arch Linux has an example to test installation (again, output to file) which also passed.

What am I missing? What could cause NetworkX & PyGraphViz to work fine alone but not together?

like image 401
xtian Avatar asked Feb 08 '16 21:02

xtian


People also ask

What can NetworkX do?

NetworkX is a package for the Python programming language that's used to create, manipulate, and study the structure, dynamics, and functions of complex graph networks.

Can NetworkX handle large graphs?

NX is certainly capable of handling graphs that large, however, performance will largely be a function of your hardware setup. Aric will likely give a better answer, but NX loads graphs into memory at once, so in the ranges your are describing you will need a substantial amount of free memory for it to work.

What is a NetworkX object?

NetworkX provides data structures and methods for storing graphs. All NetworkX graph classes allow (hashable) Python objects as nodes and any Python object can be assigned as an edge attribute. The choice of graph class depends on the structure of the graph you want to represent.


2 Answers

There is a small bug in the draw_graphviz function in networkx-1.11 triggered by the change that the graphviz drawing tools are no longer imported into the top level namespace of networkx.

The following is a workaround

In [1]: import networkx as nx

In [2]: G = nx.complete_graph(5)

In [3]: from networkx.drawing.nx_agraph import graphviz_layout

In [4]: pos = graphviz_layout(G)

In [5]: nx.draw(G, pos)

To use the other functions such as to_agraph, write_dot, etc you will need to explicitly use the longer path name

 nx.drawing.nx_agraph.write_dot()

or import the function into the top-level namespace

from networkx.drawing.nx_agraph import write_dot()
write_dot()

These command use graphviz to calculate the positioning of the nodes (graphviz_layout uses neato per default), and matplotlib to actually plot (i.e. draw) the graph.

like image 153
Aric Avatar answered Oct 17 '22 22:10

Aric


nx.nx_pydot.graphviz_layout() seems to be the way to use graphviz_layout in Networkx release 1.11.

You may need to install Graphviz via

sudo apt-get install graphviz

Some example code from the documentation:

import networkx as nx
G = nx.complete_graph(4)
pos = nx.nx_pydot.graphviz_layout(G)

I suggest this as the Graphviz_layout documentation for 1.11

like image 3
Utku Avatar answered Oct 17 '22 23:10

Utku