Distorted path in some paths

I am new to graphviz. I wanted to draw the five state multistate model. When I added some paths the paths are distorted. How to modify this problem.
I am thinking to reduce the paths between “Unhealthy working” and “Unhealthy not working” so that I can have a straight path from “Healthy working” to Dead and also from “Healthy not working” to Dead.

My code is
digraph flow {

   # set characteristics 
        width = 10,
        fixedsize = true,
        width = 1;
        #ordering = "in",
        fontname = "helvetica" # this may be OS dependent
        #constraint = false;
   nodesep=1; #hack
   A[label="Healthy \nworking", fillcolor = blue];
   B[label="Healty \nnot working", fillcolor = blue];
   C[label="Unhealthy \nworking", fillcolor = blue];
   D[label="Unhealthy \nnot working", fillcolor = blue];
   E[label=Dead, fillcolor = red];       

   # Graph
   B -> A[color = green];
   C -> D[color = blue];
   A -> D[color = blue];
   D -> A[color = green];
   B -> C[color = blue];
   C -> B[color = green];
   C -> E[color = red];
   D -> E[color = red];
   B -> E[dir = forward];
   A -> E[dir = forward];
   B -> D[color = blue];
   D -> B[color = green];
   A -> C[color = blue];
   C -> A[color = green];
   {rank=same; A -> B[color = blue]};
   {rank=same; C -> D[dir=back; color = green]};


Any help will be appreciated.


I don’t understand what distorted means in this context. Could you include a sketch showing what you are after?
p.s. if you want straight edges (not curved), use splines=false

I the plot I have uploaded, the node Dead is not in the middle between the nodes Unhealthy working and Unhealthy not working. Because of this the edges from Healthy not working to Dead is pulling more towards right side and the edge from Healthy working to Dead is also pulling more to the right. So both sides are not symmetric. Without these two edges the node Dead is exactly in the middle between the nodes Unhealthy Unhealthy working and Unhealthy not working.

Is it possible to shorten the edge between Unhealthy working and Unhealthy Unhealthy not working?

Please kindly suggest

OK, I think you are asking for left/right symmetry of the node placement. (and seemingly you are a bit more relaxed about edge placement).
Here are two ways to go about it:

  1. Explicitly alter (edit) the X component of the “Dead” node position:
    • change the output format to dot (from jpeg, png, or whatever it currently is)
    • edit the X component of the “Dead” node’s pos value to move it to the left (by calculating the mid-point or be eyeballing it) using any text editor
    • using some variant of this command, produce an output image: neato -n -Tpng myeditedfile.gv > myout.png
    • this will tell you more: FAQ
  2. Try to coerce dot to move “Dead” to the left (much more fiddly)
    • maybe adding some set of invisible nodes to the right & left of E might reposition it
    • I tried adding port specifications to some of the edges, but made things worse

I would use method #1
Note that symmetry does not seem to be part of the dot algorithm… For small diagrams, maybe a different language would be better (TikZ or gpic/dpic)

I replicated your problem, and isolated the lack of symmetry to the 'minlen' attribute you are specifying in the default edge attribute list. What I found was that if I set minlen="1" or minlen="3" the desired symmetry was present, but for some odd reason minlen="2" causes there to be an imbalance.

With minlen="1" the diagram was quite dense, and with minlen="3" it was quite large. My suggestion is to remove the minlen attribute from the edge default attribute list, and increase the ranksep attribute from ranksep="1" to ranksep="2". These changes spread the nodes further apart, and the edge routing algorithm can do its work without the minlen restriction. This change will produce the following diagram:

In the spirit of helping someone new to Graphviz, here are some other observations from your DOT file, and coding habits I follow:

  1. I shy away from using dir="forward" or dir="back" on edges, and always write my edge specifications as from_node -> to_node. The exception is dir="both", when I need arrowheads on both sides of the edge.

  2. I personally place my subgraphs which apply rank="same" near the top of my DOT file, and I do not specify style attributes or edges as part of the subgraph. While what you are doing is valid syntax, I tend to break it into multiple statements. I start by just ranking my nodes together for clarity in the statement. For example, { rank="same"; "A"; "B"; } Next I follow with node attributes after the subgraph statement, and then I define my edges. For example:

    {rank="same"; "A"; "B";}
    {rank="same"; "C"; "D";}
    "A"[ fillcolor="blue" label="Healthy\nworking" ];
    "B"[ fillcolor="blue" label="Healthy\nnot working" ];
    "C"[ fillcolor="blue" label="Unhealthy\nworking" ];
    "D"[ fillcolor="blue" label="Unhealthy\nnot working" ];
    "E"[ fillcolor="red" label="Dead" ];
    "B" -> "A"[ color="green" ];

Here is your complete DOT file adapted to produce the image above:

strict digraph "main"

    node[ shape="rectangle" height="0.5" width="1" fixedsize="True" fillcolor="Lavender" penwidth="2" fontname="Arial" fontsize="12" fontcolor="White" style="filled" ];
    edge[ color="black" penwidth="1" arrowsize="0.5" ];
    {rank="same"; "A"; "B";}
    {rank="same"; "C"; "D";}
    "A"[ fillcolor="blue" label="Healthy\nworking" ];
    "B"[ fillcolor="blue" label="Healthy\nnot working" ];
    "C"[ fillcolor="blue" label="Unhealthy\nworking" ];
    "D"[ fillcolor="blue" label="Unhealthy\nnot working" ];
    "E"[ fillcolor="red" label="Dead" ];
    "B" -> "A"[ color="green" ];
    "C" -> "A"[ color="green" ];
    "D" -> "A"[ color="green" ];
    "A" -> "B"[ color="blue" ];
    "C" -> "B"[ color="green" ];
    "D" -> "B"[ color="green" ];
    "A" -> "C"[ color="blue" ];
    "B" -> "C"[ color="blue" ];
    "D" -> "C"[ color="green" ];
    "A" -> "D"[ color="blue" ];
    "B" -> "D"[ color="blue" ];
    "C" -> "D"[ color="blue" ];
    "A" -> "E";
    "B" -> "E";
    "C" -> "E"[ color="red" ];
    "D" -> "E"[ color="red" ];

Please note that I recreated your DOT file using Excel to Graphviz, which is partially responsible for the syntax/style of the code (e.g. sorting of edges, quotes on all IDs, semi-colons on all line endings). Excel to Graphviz is a free tool for Windows and Mac Excel users which can be obtained here.

I hope you find this information helpful.

1 Like