Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tighten the dot graph making it more symmetric

I compile the following graph with: dot graph.dot -Tpdf -ograph.pdf, producing:

enter image description here

The result is okay, but the state transition look a lot like a spagetthi monster and I have no clue what I could do to approach this problem. I tried other layouts: twopi, neato, etc. Are there parameters which allow it to force the graph to look a little bit more symmetric? Because the overall picture is okay.

To me it seems like the edges use the minimal space available to frame the edge descriptions, maybe this is the problem?

Is my graph design flawed? Should I write the different state transitions on one edge, using \n to separate the different transitions?

digraph finite_state_machine {
    rankdir=LR;
    edge [fontsize=26];
    node [shape = doublecircle, width=2.0, fontsize=24, fixedsize=true,style=filled, colorscheme=spectral5]; New  [fillcolor=3] Terminated [fillcolor=5];
    node [shape = circle, width=2.0, fontsize=24, fixedsize=true, colorscheme=spectral5]; Runnable [fillcolor=4] Waiting [fillcolor=2] "Timed\nWaiting" [fillcolor=2] Blocked [fillcolor=1];
    New -> Runnable [ label = "Thread.start" ];
    Runnable -> Waiting [ label = "Object.wait" ];
    Runnable -> Waiting [ label = "Thread.sleep" ];
    Runnable -> Waiting [ label = "LockSupport.park" ];
    Waiting -> Blocked [ label = "Reacquire monitor lock after\nleaving Object.wait" ]
    Waiting -> Blocked [label = "Spurious wake-up"]
    "Timed\nWaiting" -> Blocked [ label = "Reaquire monitor lock after\n leaving Object.wait" ]
    "Timed\nWaiting" -> Terminated [ label = "Exception" ]
    "Timed\nWaiting" -> Blocked [ label = "Spurious wake-up" ]
    Runnable -> "Timed\nWaiting" [ label = "Object.wait" ];
    Runnable -> Blocked [ label = "Contended Monitor\nEnter" ];
    Blocked -> Runnable [ label = "Contended Monitor\nEntered" ];
    Runnable -> Terminated [ label = "Thread finishes\nexecution" ]
    Runnable -> Terminated [ label = "Exception" ]
    Waiting -> Runnable [ label = "Object.notify\nObject.notifyAll" ]
        Waiting -> Terminated [ label = "Exception" ]
    "Timed\nWaiting" -> Runnable [ label = "Object.notify\nObject.notifyAll" ]
}
like image 493
Konrad Reiche Avatar asked Jul 15 '11 23:07

Konrad Reiche


People also ask

What is the DOT language called?

What is Braille? Braille is a system of touch reading and writing for blind persons in which raised dots represent the letters of the alphabet. It also contains equivalents for punctuation marks and provides symbols to show letter groupings.

What is graphviz Neato?

neato is a reasonable default tool to use for undirected graphs that aren't too large (about 100 nodes), when you don't know anything else about the graph. neato attempts to minimize a global energy function, which is equivalent to statistical multi-dimensional scaling.

How do you make a graph on graphviz?

Create a graph object, assemble the graph by adding nodes and edges, and retrieve its DOT source code string. Save the source code to a file and render it with the Graphviz installation of your system. Use the view option/method to directly inspect the resulting (PDF, PNG, SVG, etc.) file with its default application.

What is graphviz in Python?

Graphviz is an open-source graph visualisation software. The graphviz package, which works under Python 3.7+ in Python, provides a pure-Python interface to this software. This package allows to create both undirected and directed graphs using the DOT language.


1 Answers

I don't think your design is flawed, I think it's ok. The dot syntax is readable and therefore maintainable, and the result is what an automatically generated graph looks typically alike.

Of course you can add small corrections to make this particular graph better (or at least different). Some of them may prove difficult to implement if for example the source for your graph is generated by an application. Here are some ideas:


To get the layout to be more symmetric, you may try to align the nodes Waiting and Terminated as well as Timed Waiting and Blocked by setting their group attribute to the same value (group=a and group=b).

grouped nodes

It worked fine for Waiting and Teminated, but not so well for Timed Waiting and Blocked - probably because there are two edges between those nodes.

You may try to straighten them out by picking one of the edges which links them and set its weight attribute to a high value.

Other than that, I think the graph looks nicer over all because the edges are smoother and have less unnecessary curves, especially - but not only - between Runnable and Waiting.


The spaghetti effect is due to the splines - maybe it looks less spaghetti without splines? I tried by adding splines=compound or splines=ortho (same result):

group and compound

The graph uses slightly less vertical space. It's not spaghetti, but it's not better in my opinion...


You may also try splines=compound without the group attributes, this should make the graph a little more compact (bug not necessarily prettier). Or simply play around with the weight of the edges to straighten out particularly unpleasant edges.

In some cases, concentrate can clear up graphs with lots of parallel edges - in this case it doesn't really help.

like image 178
marapet Avatar answered Oct 17 '22 19:10

marapet