Using networkX to output a tree structure - python

I am using networkX to generate a tree structure as follows (I am following the answer of this question).
import networkx as nx
import matplotlib.pyplot as plt
G = nx.DiGraph()
G.add_node("ROOT")
for i in range(5):
G.add_node("Child_%i" % i)
G.add_node("Grandchild_%i" % i)
G.add_node("Greatgrandchild_%i" % i)
G.add_edge("ROOT", "Child_%i" % i)
G.add_edge("Child_%i" % i, "Grandchild_%i" % i)
G.add_edge("Grandchild_%i" % i, "Greatgrandchild_%i" % i)
# write dot file to use with graphviz
# run "dot -Tpng test.dot >test.png"
nx.write_dot(G,'test.dot')
# same layout using matplotlib with no labels
plt.title('draw_networkx')
pos=nx.graphviz_layout(G, prog='dot')
nx.draw(G, pos, with_labels=False, arrows=False)
plt.savefig('nx_test.png')
I want to draw a tree as in the following figure.
However, I am getting an error saying AttributeError: module 'networkx' has no attribute 'write_dot'. My networkx version is 1.11 (using conda). I tried different hacks, but none of them worked.
So, I am interested in knowing if there is another way of drawing tree structures using networkx to get an output similar to the one mentioned in the figure. Please let me know.

You can draw digraph entirely with pygraphviz.
Following steps needs to be followed first as pygraphviz does not work without graphviz (as of now).
Download graphviz-2.38.msi from http://www.graphviz.org/Download_windows.php and install
Download the 2.7 or 3.4 pygraphviz wheel file from http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygraphviz
Navigate to the directory that you downloaded the wheel file and run your platform specific wheel
pip install pygraphviz‑1.3.1‑cp34‑none‑win32.whl
Add dot.exe to host path
e.g. on windows control-panel ->system -> edit environment variables -> Modify PATH
After that dot and png files can be created as below.
Working Code
import pygraphviz as pgv
G=pgv.AGraph(directed=True)
#Attributes can be added when adding nodes or edge
G.add_node("ROOT", color='red')
for i in range(5):
G.add_node("Child_%i" % i, color='blue')
G.add_node("Grandchild_%i" % i, color='blue')
G.add_node("Greatgrandchild_%i" % i, color='blue')
G.add_edge("ROOT", "Child_%i" % i, color='blue')
G.add_edge("Child_%i" % i, "Grandchild_%i" % i, color='blue')
G.add_edge("Grandchild_%i" % i, "Greatgrandchild_%i" % i, color='blue')
# write to a dot file
G.write('test.dot')
#create a png file
G.layout(prog='dot') # use dot
G.draw('file.png')
PNG File

I think this issue was solved on networkx 2.x, but before that you should be explicit import of the function like this.
from networkx.drawing.nx_agraph import write_dot
or
from networkx.drawing.nx_pydot import write_dot
I hope this works.

Related

How to make community detection with networkx module works?

I am working with networkx library for graph optimization problems. However, when I try running the example on their documentation it says in my PyCharm IDE after executing the example:
Traceback (most recent call last):
File "/home/PycharmProjects/testing_things.py", line 1, in <module>
import community
ImportError: No module named community
Does anyone knows how to get rid of this error? I am using Python 2.7
It would seem that your python installation doesn't have community installed.
You can install it by running:
pip install python-louvain
Cheers!
you can use :
conda install python-louvain
Use pip to install Python-Louvain:
pip install python_louvain
then in your script import the module directly using:
from community import community_louvain
In your code, use the function in the following way:
partition = community_louvain.best_partition(G)
Here's the sample community detection on the famous karate club graph based on Louvain Community Detection Algorithm:
# Replace this with your networkx graph loading depending on your format!
r = nx.karate_club_graph()
#first compute the best partition
partition = community.best_partition(r)
#drawing
size = float(len(set(partition.values())))
pos = nx.spring_layout(r)
count = 0
for com in set(partition.values()) :
count = count + 1.
list_nodes = [nodes for nodes in partition.keys()
if partition[nodes] == com]
nx.draw_networkx_nodes(r, pos, list_nodes, node_size = 20,
node_color = str(count / size))
nx.draw_networkx_edges(r, pos, alpha=0.5)
plt.show()

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?
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.
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

Graph Theory in Networkx

I am starting to use this interface now, I have some experience with Python but nothing extensive. I am calculating the transitivity and community structure of a small graph:
import networkx as nx
G = nx.read_edgelist(data, delimiter='-', nodetype=str)
nx.transitivity(G)
#find modularity
part = best_partition(G)
modularity(part, G)
I get the transitivity just fine, however - there is the following error with calculating modularity.
NameError: name 'best_partition' is not defined
I just followed the documentation provided by the networkx site, is there something I am doing wrong?
As far as I can tell best_partition isn't part of networkx. It looks like you want to use https://sites.google.com/site/findcommunities/ which you can install from https://bitbucket.org/taynaud/python-louvain/src
Once you've installed community try this code:
import networkx as nx
import community
import matplotlib.pyplot as plt
G = nx.random_graphs.powerlaw_cluster_graph(300, 1, .4)
nx.transitivity(G)
#find modularity
part = community.best_partition(G)
mod = community.modularity(part,G)
#plot, color nodes using community structure
values = [part.get(node) for node in G.nodes()]
nx.draw_spring(G, cmap = plt.get_cmap('jet'), node_color = values, node_size=30, with_labels=False)
plt.show()
edit: How I installed the community detection library
ryan#palms ~/D/taynaud-python-louvain-147f09737714> pwd
/home/ryan/Downloads/taynaud-python-louvain-147f09737714
ryan#palms ~/D/taynaud-python-louvain-147f09737714> sudo python3 setup.py install
I just met the same error NameError: name 'best_partition' is not defined when using this example code.
This error occurs because I named my python file as networkx.py, then when we execute this program
import networkx as nx
This program may import the networkx we defined instead of the library. In the program, best_partition is not defined. So this error occur.
Having same name with library is not appropriate. Maybe you should check this!

Python Mlab - cannot import name find_available_releases

I am new to Python. I am trying to run MATLAB from inside Python using the mlab package. I was following the guide on the website, and I entered this in the Python command line:
from mlab.releases import latest_release
The error I got was:
cannot import name find_available_releases
It seems that under matlabcom.py there was no find_available_releases function.
May I know if anyone knows how to resolve this? Thank you!
PS: I am using Windows 7, MATLAB 2012a and Python 2.7
I skimmed through the code, and I don't think all of the README file and its documentation match what's actually implemented. It appears to be mostly copied from the original mlabwrap project.
This is confusing because mlabwrap is implemented using a C extension module to interact with the MATLAB Engine API. However the mlab code seems to have replaced that part with a pure Python implementation as the MATLAB-bridge backend. It comes from "Dana Pe'er Lab" and it uses two different methods to interact with MATLAB depending on the platform (COM/ActiveX on Windows and pipes on Linux/Mac).
Now that we understand how the backend is implemented, you can start looking at the import error.
Note: the Linux/Mac part of the code tries to find the MATLAB executable in some hardcoded fixed locations, and allows to choose between different versions.
However you are working on Windows, and the code doesn't really implement any way of picking between MATLAB releases for this platform (so all of the methods like discover_location and find_available_releases are useless on Windows). In the end, the COM object is created as:
self.client = win32com.client.Dispatch('matlab.application')
As explained here, the ProgID matlab.application is not version-specific, and will simply use whatever was registered as the default MATLAB COM server. We can explicitly specify what MATLAB version we want (assuming you have multiple installations), for instance matlab.application.8.3 will pick MATLAB R2014a.
So to fix the code, IMO the easiest way would be to get rid of all that logic about multiple MATLAB versions (in the Windows part of the code), and just let it create the MATLAB COM object as is. I haven't attempted it, but I don't think it's too involved... Good luck!
EDIT:
I download the module and I managed to get it to work on Windows (I'm using Python 2.7.6 and MATLAB R2014a). Here are the changes:
$ git diff
diff --git a/src/mlab/matlabcom.py b/src/mlab/matlabcom.py
index 93f075c..da1c6fa 100644
--- a/src/mlab/matlabcom.py
+++ b/src/mlab/matlabcom.py
## -21,6 +21,11 ## except:
print 'win32com in missing, please install it'
raise
+def find_available_releases():
+ # report we have all versions
+ return [('R%d%s' % (y,v), '')
+ for y in range(2006,2015) for v in ('a','b')]
+
def discover_location(matlab_release):
pass
## -62,7 +67,7 ## class MatlabCom(object):
"""
self._check_open()
try:
- self.eval('quit();')
+ pass #self.eval('quit();')
except:
pass
del self.client
diff --git a/src/mlab/mlabraw.py b/src/mlab/mlabraw.py
index 3471362..16e0e2b 100644
--- a/src/mlab/mlabraw.py
+++ b/src/mlab/mlabraw.py
## -42,6 +42,7 ## def open():
if is_win:
ret = MatlabConnection()
ret.open()
+ return ret
else:
if settings.MATLAB_PATH != 'guess':
matlab_path = settings.MATLAB_PATH + '/bin/matlab'
diff --git a/src/mlab/releases.py b/src/mlab/releases.py
index d792b12..9d6cf5d 100644
--- a/src/mlab/releases.py
+++ b/src/mlab/releases.py
## -88,7 +88,7 ## class MatlabVersions(dict):
# Make it a module
sys.modules['mlab.releases.' + matlab_release] = instance
sys.modules['matlab'] = instance
- return MlabWrap()
+ return instance
def pick_latest_release(self):
return get_latest_release(self._available_releases)
First I added the missing find_available_releases function. I made it so that it reports that all MATLAB versions are available (like I explained above, it doesn't really matter because of the way the COM object is created). An even better fix would be to detect the installed/registered MATLAB versions using the Windows registry (check the keys HKCR\Matlab.Application.X.Y and follow their CLSID in HKCR\CLSID). That way you can truly choose and pick which version to run.
I also fixed two unrelated bugs (one where the author forgot the function return value, and the other unnecessarily creating the wrapper object twice).
Note: During testing, it might be faster NOT to start/shutdown a MATLAB instance each time the script is called. This is why I commented self.eval('quit();') in the close function. That way you can start MATLAB using matlab.exe -automation (do this only once), and then repeatedly re-use the session without shutting it down. Just kill the process when you're done :)
Here is a Python example to test the module (I also show a comparison against NumPy/SciPy/Matplotlib):
test_mlab.py
# could be anything from: latest_release, R2014b, ..., R2006a
# makes no difference :)
from mlab.releases import R2014a as matlab
# show MATLAB version
print "MATLAB version: ", matlab.version()
print matlab.matlabroot()
# compute SVD of a NumPy array
import numpy as np
A = np.random.rand(5, 5)
U, S, V = matlab.svd(A, nout=3)
print "S = \n", matlab.diag(S)
# compare MATLAB's SVD against Scipy's SVD
U, S, V = np.linalg.svd(A)
print S
# 3d plot in MATLAB
X, Y, Z = matlab.peaks(nout=3)
matlab.figure(1)
matlab.surf(X, Y, Z)
matlab.title('Peaks')
matlab.xlabel('X')
matlab.ylabel('Y')
matlab.zlabel('Z')
# compare against matplotlib surface plot
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='jet')
ax.view_init(30.0, 232.5)
plt.title('Peaks')
plt.xlabel('X')
plt.ylabel('Y')
ax.set_zlabel('Z')
plt.show()
Here is the output I get:
C:\>python test_mlab.py
MATLAB version: 8.3.0.532 (R2014a)
C:\Program Files\MATLAB\R2014a
S =
[[ 2.41632007]
[ 0.78527851]
[ 0.44582117]
[ 0.29086795]
[ 0.00552422]]
[ 2.41632007 0.78527851 0.44582117 0.29086795 0.00552422]
EDIT2:
The above changes have been accepted and merged into mlab.
You are right in saying that the find_available_releases() is not written. 2 ways to work this out
Check out the code in linux and work on it (You are working on
windows !)
Change the Code as below
Add the following function in matlabcom.py as in matlabpipe.py
def find_available_releases():
global _RELEASES
if not _RELEASES:
_RELEASES = list(_list_releases())
return _RELEASES
If you see mlabraw.py file, the following code will give you a clear idea why I am saying this !
import sys
is_win = 'win' in sys.platform
if is_win:
from matlabcom import MatlabCom as MatlabConnection
from matlabcom import MatlabError as error
from matlabcom import discover_location, find_available_releases
from matlabcom import WindowsMatlabReleaseNotFound as MatlabReleaseNotFound
else:
from matlabpipe import MatlabPipe as MatlabConnection
from matlabpipe import MatlabError as error
from matlabpipe import discover_location, find_available_releases
from matlabpipe import UnixMatlabReleaseNotFound as MatlabReleaseNotFound

Running Graph library with nodebox on windows + None Type Error

I have installed nodebox 2 for windows on my machine and have verified that all the examples are running as it is.
Now i want to use graph library Graph for the same.
I went and copied it as it is in my site-packages folder and then ran the examples it had given along it in IDLE.
I recieved an error of ximport . So then i added in the code as from nodebox.graphics import *
Now i get the following error
Traceback (most recent call last):
File "C:\Python26\Lib\site-packages\graph\graph_example2.py", line 39, in <module>
g.draw(highlight=path, weighted=True, directed=True)
File "C:\Python26\lib\site-packages\graph\__init__.py", line 453, in draw
self.update()
File "C:\Python26\lib\site-packages\graph\__init__.py", line 416, in update
self.x = _ctx.WIDTH - max.x*self.d - min_.x*self.d
AttributeError: 'NoneType' object has no attribute 'WIDTH'
Is there any way I can run this library from outside of nodebox in windows ?
thanks...
I am pasting the code for which i get the error below...
from nodebox.graphics import *
try:
graph = ximport("graph")
except ImportError:
graph = ximport("__init__")
reload(graph)
size(600, 600)
# A graph object.
g = graph.create(iterations=500, distance=1.0)
# Add nodes with a random id,
# connected to other random nodes.
for i in range(50):
node1 = g.add_node(random(500))
if random() > 0.5:
for i in range(choice((2, 3))):
node2 = choice(g.nodes)
g.add_edge(node1.id, node2.id, weight=random())
# We leave out any orphaned nodes.
g.prune()
# Colorize nodes.
# Nodes with higher importance are blue.
g.styles.apply()
# Update the graph layout until it's done.
g.solve()
# Show the shortest path between two random nodes.
path = []
id1 = choice(g.keys())
id2 = choice(g.keys())
path = g.shortest_path(id1, id2)
# Draw the graph and display the shortest path.
g.draw(highlight=path, weighted=True, directed=True)
The Nodebox Graph docs mention that it supports Nodebox 1.9.5.6, which is a Nodebox 1 (Mac only) version number. To my knowledge the Graph library has not yet been ported to Nodebox 2, so can only currently run on the Mac.
One option is a project called Nodebox OpenGL which implements the Nodebox API and includes its own graph library, with an example of using it under examples\08-physics\07-graph. The Nodebox 1 Graph library is not yet compatible, but it includes its own graph class nodebox.graphics.physics.Graph.
To use it, you'll need to download:
Nodebox for OpenGL
pyglet cross platform multimedia library
Extract these and install, or just place the nodebox and pyglet packages somewhere on your Python path (site-packages). When you run 07-graph.py you should see this:

Categories

Resources