10

I'm using chains to draw a simple Markov chain. I used \draw and \path to manually add arcs between nodes. But the labels and arcs overlap badly although I used auto location for labels. Is there a way to let Tikz do this automatically? Manually adjusting distances is possible but I believe Tikz is more powerful than I know.

enter image description here

\documentclass{standalone}

\usepackage{tikz}
\begin{document}
\usetikzlibrary{automata,chains}
\begin{tikzpicture}[start chain=going right]
\node[state,on chain] (-2) {-2};
\node[state,on chain] (-1) {-1};
\node[state,on chain] (0) {0};
\node[draw=red,fill=red,state,on chain] (+1) {+1};
\node[draw=red,fill=red,state,on chain] (+2) {+2};

\draw[->] (-1) to node[auto] {$P(0)$}(-2);
\path[->] (-1) edge  [loop above] node[auto] {$P(1)$} ();
\draw[->] (-1) to node[auto] {$P(2)$}(0);
\draw[->] (-1) to[bend right] node[auto] {$P(3)$}(+1);
\draw[->] (-1) to[bend right] node[auto] {$P(4)$}(+2);

\draw[->] (+1) to node[above]{$1$} (0);
\draw[->] (+2) to[bend right] node[above]{$1$} (0);
\end{tikzpicture}
\end{document}
5

Here is another approach.

In some cases when you have lots of nearby arcs, it is not a bad idea to put the labels on the arcs themselves. Here is an example from some previous work of mine:

My example figure.

With this in mind, here is how I would typeset your figure:

\documentclass[margin=2mm]{standalone}

\usepackage{tikz}
\usetikzlibrary{automata,chains}

\begin{document}

\begin{tikzpicture}[start chain=going right]
  \tikzset{%
    in place/.style={
      auto=false,
      fill=white,
      inner sep=2pt,
    },
  }
  %
  \node[state,on chain]                   (-2) {$-2$};
  \node[state,on chain]                   (-1) {$-1$};
  \node[state,on chain]                   (0)  {$0$};
  \node[draw=red,fill=red,state,on chain] (+1) {$+1$};
  \node[draw=red,fill=red,state,on chain] (+2) {$+2$};
  \draw[->, auto]
    (-1) edge node[swap] {$P(0)$} (-2)
    (-1) edge[loop above] node {$P(1)$} ()
    (-1) edge node {$P(2)$} (0)
    (-1) edge[bend right=35] node[pos=0.7, in place] {$P(3)$} (+1)
    (-1) edge[bend right=35] node[pos=0.7, in place] {$P(4)$} (+2)
    (+1) edge node[swap] {$1$} (0)
    (+2) edge[bend right] node[swap] {$1$} (0)
    ;
\end{tikzpicture}

\end{document}

Please note that

  • I have grouped all your edges into one \draw operation;
  • because of this, I can specify the auto option just once, and
  • swap edges that appear on the "wrong" side, while
  • the in place style (defined at the top of the figure) disables auto for a single node.

I also increased the bend angle a bit (from the default of 30 degrees) to give your arcs a bit more breathing room.

Finally, note that your numbers should be typeset in math mode. Compare the $-1$ in my figure to the -1 in your original.

My rendering of your example.

  • Nice! I like this. – pschulz Feb 8 '17 at 6:06
10

The auto option is not magic. Its effect depends on the current direction, so it cannot take surrounding drawings into effect. You will have to interfer manually, but there are ways to make this feel kind of automatic. The easiest way to fix this is to use an angle for the bend right style:

\documentclass{standalone}

\usepackage{tikz}
\begin{document}
\usetikzlibrary{automata,chains}
\begin{tikzpicture}[start chain=going right]
\node[state,on chain] (-2) {-2};
\node[state,on chain] (-1) {-1};
\node[state,on chain] (0) {0};
\node[draw=red,fill=red,state,on chain] (+1) {+1};
\node[draw=red,fill=red,state,on chain] (+2) {+2};

\draw[->] (-1) to node[auto] {$P(0)$}(-2);
\path[->] (-1) edge  [loop above] node[auto] {$P(1)$} ();
\draw[->] (-1) to node[auto] {$P(2)$}(0);
\draw[->] (-1) to[bend right=60] node[auto] {$P(3)$}(+1);
\draw[->] (-1) to[bend right=60] node[auto] {$P(4)$}(+2);
%                           ^^^ change is here

\draw[->] (+1) to node[above]{$1$} (0);
\draw[->] (+2) to[bend right] node[above]{$1$} (0);
\end{tikzpicture}
\end{document}

This yields: result

But i would suggest the following, for consistency (also, i like explicit positioning, but that is a matter of taste):

\draw[->] (-1) to[bend right=30] node[below] {$P(3)$}(+1);
\draw[->] (-1) to[bend right=50] node[below] {$P(4)$}(+2);

This yields Result 2

7

Use the auto option globally and add swap to those nodes that end up on the wrong side.

enter image description here

\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{automata,chains}
\begin{document}
\begin{tikzpicture}[start chain=going right,auto]
\node[state,on chain] (-2) {-2};
\node[state,on chain] (-1) {-1};
\node[state,on chain] (0) {0};
\node[draw=red,fill=red,state,on chain] (+1) {+1};
\node[draw=red,fill=red,state,on chain] (+2) {+2};

\draw[->] (-1) to node[swap] {$P(0)$}(-2);
\path[->] (-1) edge  [loop above] node {$P(1)$} ();
\draw[->] (-1) to node {$P(2)$}(0);
\draw[->] (-1) to[bend right] node[swap] {$P(3)$}(+1);
\draw[->] (-1) to[bend right=50] node[swap] {$P(4)$}(+2);

\draw[->] (+1) to node[swap]{$1$} (0);
\draw[->] (+2) to[bend right] node[swap]{$1$} (0);
\end{tikzpicture}
\end{document}
7

For exercise: how to make OP code shorter and without overlapping of edges labels. With use of quotes library, and predefined edge angle, and reduced labels' font size to \footnotesize:

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{automata, chains, quotes}

\begin{document}
    \begin{tikzpicture}[auto,
     bend angle = 45,
    start chain = going right,
every state/.append style = {on chain},
every edge quotes/.style = {inner sep=2pt, font=\footnotesize}
                        ]
\node[state] (-2) {$-2$};
\node[state] (-1) {$-1$};
\node[state] (0)   {0};
\node[state,draw=red,fill=red] (+1) {$+1$};
\node[state,draw=red,fill=red] (+2) {$+2$};

\draw[->]   (-1) edge["$P(0)$"] (-2)
            (-1) edge[loop above,  "$P(1)$"] ()
            (-1) edge["$P(2)$"] (0)
            (-1) edge[bend right,"$P(3)$"] (+1)
            (-1) edge[bend right,"$P(4)$"] (+2)%change is here
            (+1) edge["$1$"]    (0)
            (+2) edge[bend right,"$1$"] (0);
\end{tikzpicture}
\end{document}

the image of the automaton become:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.