Tuesday, June 17, 2014

Fixed order graphs with Graphviz

Graphviz continues to amaze me. I did not know until recently that they had an awk-like language for graphs within the graphviz package, but even closer home - there's a tool to control the order of nodes!

This is the one thing I've battled with out-of-the-box Graphviz for a long time - any new edge is likely to throw your neat-looking graph off-kilter *just because* that's the most optimal graph layout.

Well, not if you use osage, packmode and sortv.

I dont exactly know why its called osage, but this layouting engine actually obeys the order of nodes that you can specify with the sortv attribute.

You have to set the appropriate packmode setting, of course, and the correct incantation is:

packmode=array_uX

where X=1 if you want one column of nodes, 2 if two and so forth.

Here's a sample graph for a taste of what it looks like in practice (from the man page for osage, see example section):

digraph test123 {
    pack=8
    subgraph cluster0 {
        packmode=array_u1
        x[sortv=5]
        y[sortv=4]
        x0[sortv=3]
        y0[sortv=2]
        x1[sortv=1]
       
        subgraph cluster1 {
            mn
        }
    }
    b[shape=box];
    c[label="hello\nworld",color=blue,fontsize=24,fontname="Palatino−Italic",fontcolor=red,style=filled];

    a->z
    x->z
    a->b->c;
    a->{x y};

    edge [style=dashed,color=red];
    b->x;
}



Once you do that, you issue something like this:

osage testosage.dot -Tpng -o testosage.png

... and you should see a column of components with x at the bottom and x1 at the top.

Also, use

pack=16

to space the nodes out a bit. Default is 8