Search code examples
graphvizdot2tex

Specifying nodes on horizontal lines


I have tried several to draw a graph representing with consecutive states in a straight line, S0 -> S1 -> S2. Then actions in another straight line below. There are edges between S0 -> A0 -> S1 -> A1 -> S2. Which forms triangles lined up next to each other.
desired output with states and actions on horizontal lines

I have tried to use a cluster, and rank=same for the nodes I want to align. I also tried to use [constraint=false] and other answers on Stack Overflow.

\begin{dot2tex}[fdp]
digraph G {
    newrank=true;
    node[group="states"]
    S0 [texlbl="$S_{t-2}$", shape=none];
    S1 [texlbl="$S_{t-1}$", shape=none];
    S2 [texlbl="$S_t$", shape=none];
    S3 [texlbl="$S_{t+1}$", shape=none];
    node[group=""]
    A0 [texlbl="$A_{t-2}$", shape=none];
    A1 [texlbl="$A_{t-1}$", shape=none];
    A2 [texlbl="$A_t$", shape=none];
    { rank=same; S0; S1; S2; S3;
    S0 -> S1-> S2 -> S3;
    S0 -> A0;
    S1 -> A1;
    S2 -> A2; }
    A0 -> S1;
    A1 -> S2;
    A2 -> S3;
}
\end{dot2tex}

However the output from the graph is a mixture of states and actions on a curve. output showing curved graph


Solution

  • Your code looks like part of a LaTeX document but it wouldn't work for me; dot2tex is, as far as I can see, a Python script that produces LaTeX code. But I'm out of my depth here, it seems to work for you.

    What I have done - I have corrected the mistake you have made, putting the closing brace } for the rank = same instruction back into that same line, and took it out of the apparent LaTeX environment; I also changed the arrow direction for the edges showing "upwards". Then I commented out the unnecessary instructions, arriving at

    digraph G {
    #    newrank=true;
    #    node[group="states"]
        S0 [texlbl="$S_{t-2}$", shape=none];
        S1 [texlbl="$S_{t-1}$", shape=none];
        S2 [texlbl="$S_t$", shape=none];
        S3 [texlbl="$S_{t+1}$", shape=none];
    #    node[group=""]
        A0 [texlbl="$A_{t-2}$", shape=none];
        A1 [texlbl="$A_{t-1}$", shape=none];
        A2 [texlbl="$A_t$", shape=none];
        { rank=same; S0; S1; S2; S3; }
        S0 -> S1-> S2 -> S3;
        S0 -> A0;
        S1 -> A1;
        S2 -> A2;
        edge[ dir = back ];
        S1 -> A0;
        S2 -> A1;
        S3 -> A2;
    }
    

    Converting this to a LaTex document with

    dot2tex -ftikz x > x.tex
    

    I get

    enter image description here

    which I guess is what you want, or at least, what your code will produce. Your workflow may be different, but if you correct the main mistake and move the closing brace where it belongs, you should be done. Note that dot2tex uses the dot engine by default, which is what you should be doing, as rightly pointed out be @Dany.

    If you want something that is close to the picture in your post, try

    digraph G 
    {
        node[ shape =none ]
    
        S  [ label = "" ];
        S0 [ texlbl="$S_{t-2}$" ];
        S1 [ texlbl="$S_{t-1}$" ];
        S2 [ texlbl="$S_t$" ];
        S3 [ texlbl="$S_{t+1}$" ];
    
        A0 [ texlbl="$A_{t-2}$" ];
        A1 [ texlbl="$A_{t-1}$" ];
        A2 [ texlbl="$A_t$" ];
    
        { rank=same; S S0 S1 S2 S3 }
        S0 -> S1 -> S2 -> S3
    
        S0 -> A1;
        S1 -> A2;
        edge[ dir = back ];
        S0 -> A0;
        S1 -> A1;
        S2 -> A2;
    
        edge[ style = invis ];
        S -> S1
        S -> A0;
    }
    

    enter image description here