Generating Graph Visualizations with pydot and Graphviz

9 12 2009

Hi, for my latest college assignment I had to find a way to visualize data that is interrelated. For instance, my application generated the following data:

A --> B
B --> C
B --> D

And I needed a way to generate pretty graphs without too much headache!

I am already using wxPython for the application’s UI (it saved me a lot of time, and I learned a lot in the process, even implemented my own clone of the Aero Wizard layout used in Windows Vista and 7), so I tried to look for a way to integrate some other super powered library into my app. I quickly remembered a couple of projects that used Graphviz to generate visualizations of Django model definitions: DjangoGraphviz, and django-graphviz. I even hacked one of them to generate visualizations where each app had it’s own color. But these were complicated projects, because they generated some funky XML (correct me if I’m wrong) files that where later fed to graphviz and you had to mess a little with config options.

I wanted something simpler… lucky me, I stumbled into the wonderful project pydot. It was just what I needed, after a couple of experiments I could quickly generate “fantastic” visualizations with almost no extra effort. I’m using this on my Fedora 11 x86_64 box, so I just had to install pydot and easy_install handled the dependencies (it automatically downloaded and installed pyparsing), I am not sure what the requirements for Windows are… specially to get this running with py2exe, I’ll be blogging about that later.

In any case, let me provide you with a quick “getting started” tutorial guide on how this works.

Example 1: “Easy as Pie”

Ok, let’s try an easy one, suppose you have a set of data that you want to represent in a hierarchical way… Say: King, Lords and Vassals… Let’s try to graph that with as little code as we can:

See this code formatted in dpaste.org: http://dpaste.org/YQAZ/

# -*- coding: utf-8 -*-
"""
pydot example 1
@author: Federico Cáceres
@url: http://pythonhaven.wordpress.com/2009/12/09/generating_graphs_with_pydot
"""
import pydot # import pydot or you're not going to get anywhere my friend :D

# first you create a new graph, you do that with pydot.Dot()
graph = pydot.Dot(graph_type='graph')

# the idea here is not to cover how to represent the hierarchical data
# but rather how to graph it, so I'm not going to work on some fancy
# recursive function to traverse a multidimensional array...
# I'm going to hardcode stuff... sorry if that offends you

# let's add the relationship between the king and vassals
for i in range(3):
    # we can get right into action by "drawing" edges between the nodes in our graph
    # we do not need to CREATE nodes, but if you want to give them some custom style
    # then I would recomend you to do so... let's cover that later
    # the pydot.Edge() constructor receives two parameters, a source node and a destination
    # node, they are just strings like you can see
    edge = pydot.Edge("king", "lord%d" % i)
    # and we obviosuly need to add the edge to our graph
    graph.add_edge(edge)

# now let us add some vassals
vassal_num = 0
for i in range(3):
    # we create new edges, now between our previous lords and the new vassals
    # let us create two vassals for each lord
    for j in range(2):
        edge = pydot.Edge("lord%d" % i, "vassal%d" % vassal_num)
        graph.add_edge(edge)
        vassal_num += 1

# ok, we are set, let's save our graph into a file
graph.write_png('example1_graph.png')

# and we are done!

Simple, huh? You should have a graph like this:

Graph generated by example 1

Graph generated by example 1

Now… that looks pretty boring, right? Let’s try something some more… colorful and with a different kind of graph.

Example 2: “Still Easy as Pie”

Ok, on the last example we made an undirected graph, let’s create a directed one now, and let’s also add some colors and labels on the edges between nodes. Say we have four nodes: A, B, C and D, were A points to B, B points to C, C points to D and D points back to A… let’s try that, ok?

See this code formatted in dpaste.org: http://dpaste.org/dSyE/

# -*- coding: utf-8 -*- """ pydot example 2 @author: Federico Cáceres @url: http://pythonhaven.wordpress.com/2009/12/09/generating_graphs_with_pydot """ import pydot # this time, in graph_type we specify we want a DIrected GRAPH graph = pydot.Dot(graph_type='digraph') # in the last example, we did no explicitly create nodes, we just created the edges and # they automatically placed nodes on the graph. Unfortunately, this way we cannot specify # custom styles for the nodes (although you CAN set a default style for all objects on # the graph...), so let's create the nodes manually. # creating nodes is as simple as creating edges! node_a = pydot.Node("Node A", style="filled", fillcolor="red") # but... what are all those extra stuff after "Node A"? # well, these arguments define how the node is going to look on the graph, # you can find a full reference here: # http://www.graphviz.org/doc/info/attrs.html # which in turn is part of the full docs in # http://www.graphviz.org/Documentation.php # neat, huh? Let us create the rest of the nodes! node_b = pydot.Node("Node B", style="filled", fillcolor="green") node_c = pydot.Node("Node C", style="filled", fillcolor="#0000ff") node_d = pydot.Node("Node D", style="filled", fillcolor="#976856") #ok, now we add the nodes to the graph graph.add_node(node_a) graph.add_node(node_b) graph.add_node(node_c) graph.add_node(node_d) # and finally we create the edges # to keep it short, I'll be adding the edge automatically to the graph instead # of keeping a reference to it in a variable graph.add_edge(pydot.Edge(node_a, node_b)) graph.add_edge(pydot.Edge(node_b, node_c)) graph.add_edge(pydot.Edge(node_c, node_d)) # but, let's make this last edge special, yes? graph.add_edge(pydot.Edge(node_d, node_a, label="and back we go again", labelfontcolor="#009933", fontsize="10.0", color="blue")) # and we are done graph.write_png('example2_graph.png') # this is too good to be true!

That code generates this graph:

Graph generated in example 2

Graph generated in example 2

As you can see, the possibilities are endless, using the attributes you can set for each node, edge and other forms supported by the library, you can easily visualize your data that would otherwise be very hard to see.

One more thing, you can set the attributes when initializing the Node/Edge, or you can use the set_xyz method, for instance, instead of doing this:

pydot.Edge(node_d, node_a, label="and back we go again", labelfontcolor="#009933", fontsize="10.0", color="blue")

You could do this:

edge = pydot.Edge(node_d, node_a)
edge.set_label("and back we go again")
edge.set_labelfontcolor("#009933")
edge.set_fontsize("10.0")
edge.set_color("blue")

That can come in handy.

Well, I hope you found this useful as I have, and that this mini pydot tutorial helps you with this great library.

Don’t forget to visit these links:

Till next time!

About these ads

Actions

Information

22 responses

9 12 2009
Kenny Meyer

Nice demonstration! Creating such diagrams in a Django powered website is a nice idea…

9 12 2009
Federico

Indeed, it is both fun and informative! It’s always easier to see problems in your design when it is displayed in graphs. You should check out those two projects I mentioned at the beginning of the post. I’m not sure if the are the same… or if one is the fork of another…. or if they are completely different, but I remember I used django-graphviz and it was excellent, it worked really well!

3 06 2011
Túlio

Good examples…
It will be perfect for my project.

12 07 2011
Carla

Thanks a lot!
It was not being easy for me to understand how to work with pydot, but after reading your post everything is clear :)

12 07 2011
Federico

Glad to hear my humble two year old post is still useful :).

16 04 2012
Horacio!

Federico! Fancy seeing you here!

16 04 2012
Federico

Welcome to my humble (and not so updated) blog!

19 10 2011
kingwolo

Just what I needed, thanks :)

25 01 2012
Raj

Federico … Is there a way to visualize the graph without saving it as a png file? In other words, can we use a GUI libraries like wx to read and display the graph from main memory? Thanks, Raj

16 04 2012
Federico

Hi Raj, I made an app with wxpython and pydot that “drew” graphs in realtime according to a grid that the user can use to model the graph (http://code.google.com/p/pyflowuca/). Unfortunately the source code is in spanish, but let me tell you how I did it. I just created the graphs on a temporary file using python’s tempfile module and loaded the file using wxPython bitmap loading functions. Just remember to delete the file once you’re done.

23 02 2012
Alan Yeung

Cool, looking at directive graphs in Python right now, the python-graph looks good but couldnt get it working with the brief amount of time spent today. This pydot seems to work out of the box, sweet.

Did you ever get this runing with py2exe??

16 04 2012
Federico

Hi Alan, pydot is indeed very simple to get working and use. I don’t remember having to do anything special to make pydot work with py2exe, did you get it working?

28 02 2012
samba

made so easy \m/
any pointers for pydot+boost to work in python?

16 04 2012
Federico

I’m glad this was useful for you! Unfortunately I have no experience on boost, sorry I can’t help you on that.

23 04 2012
Alan Yeung

Hi Federico,

I can build to .exe but it still requires the Graphviz.exe.

All the libs I have seen (pydot, pygraphviz) all need Graphviz installed on the computer. The issue I am having is directing Pydot or PyGraphviz to the relevant DLL’s which Py2exe pulls out correctly.

For example when I use PyGraphviz it references the Graphviz exe’s through an import _graphviz (which is .pyd file that calls the Graphviz .exe’s).

Still digging… in essence I would of thought that there was simple Pyhon libs to go from .dot to .svg without this Graphviz?? Also seen WinGraphviz.dll which I think is independant of Graphviz, just need to figure out how to use it.

26 09 2012
Mina Metias

Thank you so much, this was really straight to the point.
I wonder why pydot has such a poor documentation.

17 11 2012
Nate Rock

Thank you very much. This got me up and running with pydot in about 10 min. The one thing I didn’t do was have GraphViz installed before trying to run the code. After installing GraphViz it on Win 7 x64, it was smooth sailing.

23 07 2013
Rishi

is there any way to use pyDot to create a tree and then build a GUI application in wx using the nodes in the tree as widgets?

5 08 2013
Dependencies | Eleven Eleven

[…] documentation on pydot on their google-code page was non-existent, so I visited this blog post which helped get me started. Then with some playing around in IDLE, I came up with […]

25 08 2013
Terrence Brannon

Excellent tutorial. Just what I needed. The dpaste links to source code no longer work. Perhaps make github gists of them?

16 12 2013
Embedded Components and Tools Blog Center » Blog Archive » Visualizing Software Tree Structures

[…] Some more graphviz links graphviz gallery (crazy examples here!): http://www.graphviz.org/Gallery.php graphviz documentation: http://www.graphviz.org/Documentation.php graphviz documentation on attributes: http://www.graphviz.org/doc/info/attrs.html Generating Graph Visualizations with pydot and Graphviz http://pythonhaven.wordpress.com/2009/12/09/generating_graphs_with_pydot/ […]

17 12 2013
Pydot and trees : easy way to draw trees in python

[…] The Pydot lib is uber easy to use and there is a quick example of  it s usage here. […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




Follow

Get every new post delivered to your Inbox.

%d bloggers like this: