2

I have the following TikZ picture:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{arrows,automata,positioning}

\begin{document}
\begin{tikzpicture}[initial text={}, auto, >=stealth', node distance=0.75cm]
  \tikzstyle{every edge}=[->, draw]
  \node[state, initial] (i) {$q_0$};
  \node[state, right=of i] (0) {$0$};
  \node[state, right=of 0] (134) {$1, 3, 4$};
  \node[state, right=of 134] (25) {$2, 5$};
  \node[state, right=of 25] (13) {$1, 3$};
  \node[state, below=of 13] (2) {$2$};
  \node[state, below=of 25] (6) {$6$};
  \node[state, below=of 0] (es) {$\emptyset$};
  \node[state, accepting, right=of 13] (f) {$q_1$};

  \path (i) edge node {$1$} (0);
  \path (i) edge[bend left=60] node[above, pos=0.2] {$1$} (f);
  \path (0) edge node {$a$} (134);
  \path (0) edge node {$b$} (es);
  \path (0) edge[bend left=45] node {$1$} (f);
  \path (134) edge[loop below] node[above] {$a$} (134);
  \path (134) edge node {$b$} (25);
  \path (25) edge node {$a$} (13);
  \path (25) edge node {$b$} (6);
  \path (25) edge[bend left] node {$1$} (f);
  \path (13) edge[bend right=45] node {$a$} (134);
  \path (13) edge node {$b$} (2);
  \path (2) edge[bend left] node {$a$} (13);
  \path (2) edge[bend left] node[above] {$b$} (es);
  \path (2) edge node[pos=0.75] {$1$} (f);
  \path (6) edge node {$a$} (134);
  \path (6) edge node {$b$} (es);
  \path (es) edge[loop left] node {$a, b$} (es);
  \path (es) edge[bend right=70] node[pos=0.1, below] {$1$} (f);
\end{tikzpicture}
\end{document}

Unfortunately, TikZ generates a lot of whitespace above and below the picture, which I want to get rid of. I figured out that it is related to the edges \path (i) edge[bend left=60] node[above, pos=0.2] {$1$} (f); and \path (es) edge[bend right=70] node[pos=0.1, below] {$1$} (f); as the space changes when the values bend ...=## are changed. It seems likely that TikZ reserves space for the label nodes, which, however, is not necessary since the nodes are not in their default position.

Now for my question: what causes this behavior and how can I get rid of it?

JPW
  • 721
  • 1
    Possible solution: http://tex.stackexchange.com/a/57486/1952 – Ignasi Nov 20 '15 at 08:19
  • @Ignasi: This seems to require a lot of manual fiddling, which I would like to avoid. – JPW Nov 20 '15 at 12:57
  • I thought for a moment than replacing the bend commands with something like (for the (es) path) \path (es) edge[out=305,in=265] node[pos=0.1, below] {$1$} (f); could solve your (interesting) problem, but it didn't. Unfortunately, I think that manual fiddling is unavoidable… – Clément Nov 21 '15 at 06:19

2 Answers2

4

Version 3.1.5 of TikZ introduced a bbox library which lets you activate a better calculation for the bounding box. Due to licensing issues, that library was removed from pgf/TikZ version 3.1.6, see https://github.com/pgf-tikz/pgf/releases/tag/3.1.6, but it was later made available in a separate package, called tikz-bbox.

Hence, if you either have TikZ version 3.1.5, or the tikz-bbox package, the answer given below should work I think.


With \usetikzlibrary{bbox}, you in principle just need to add bezier bounding box=true to the options of the tikzpicture. For your case it failed miserably for two of the paths though, so I put those in a scope environment and deactivated the bounding box calculation here. Note that it does take a little bit longer to compile.

The little bit of whitespace on the left comes from the initial node, the grey bit in the screenshot is the background of the PDF viewer.

enter image description here

\documentclass{standalone}

\usepackage{tikz} \usetikzlibrary{arrows,automata,positioning,bbox} % added bbox

\begin{document} \begin{tikzpicture}[ initial text={}, auto, >=stealth', node distance=0.75cm, bezier bounding box=true, % <-- added every edge/.style={->, draw} ]

\node[state, initial] (i) {$q_0$}; \node[state, right=of i] (0) {$0$}; \node[state, right=of 0] (134) {$1, 3, 4$}; \node[state, right=of 134] (25) {$2, 5$}; \node[state, right=of 25] (13) {$1, 3$}; \node[state, below=of 13] (2) {$2$}; \node[state, below=of 25] (6) {$6$}; \node[state, below=of 0] (es) {$\emptyset$}; \node[state, accepting, right=of 13] (f) {$q_1$};

\path (i) edge node {$1$} (0); \path (i) edge[bend left=60] node[above, pos=0.2] {$1$} (f); \path (0) edge node {$a$} (134); \path (0) edge node {$b$} (es); \path (0) edge[bend left=45] node {$1$} (f); \path (134) edge node {$b$} (25); \path (25) edge node {$a$} (13); \path (25) edge node {$b$} (6); \path (13) edge[bend right=45] node {$a$} (134); \path (13) edge node {$b$} (2); \path (2) edge[bend left] node {$a$} (13); \path (2) edge[bend left] node[above] {$b$} (es); \path (2) edge node[pos=0.75] {$1$} (f); \path (6) edge node {$a$} (134); \path (6) edge node {$b$} (es); \path (es) edge[loop left] node {$a, b$} (es); \path (es) edge[bend right=70] node[pos=0.1, below] {$1$} (f);

% but deactivate for this bit \begin{scope}[bezier bounding box=false] \path (134) edge[loop below] node[above] {$a$} (134); \path (25) edge[bend left] node {$1$} (f); \end{scope}

\end{tikzpicture} \end{document}

Torbjørn T.
  • 206,688
1

It turns out that the whitespace is added because TikZ includes the control points of the edges in the picture (see What type of curve is used by Tikz when I "bend" an edge?).

This becomes apparent if one enables drawing of the control points...

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{arrows,automata,positioning}

\usetikzlibrary{decorations.pathreplacing,shapes.misc}
\tikzset{
  show control points/.style={
    decoration={show path construction, curveto code={
        \draw [blue, dashed]
        (\tikzinputsegmentfirst) -- (\tikzinputsegmentsupporta)
        node [at end, anchor=center, cross out, draw, solid, red, inner sep=2pt]{};
        \draw [blue, dashed]
        (\tikzinputsegmentsupportb) -- (\tikzinputsegmentlast)
        node [at start, anchor=center, cross out, draw, solid, red, inner sep=2pt]{};
      }
    },
    postaction=decorate
  },
}

\begin{document}
  \begin{tikzpicture}[initial text={}, auto, >=stealth', node distance=0.75cm]
  \tikzstyle{every edge}=[->, draw]
  \node[state, initial] (i) {$q_0$};
  \node[state, right=of i] (0) {$0$};
  \node[state, right=of 0] (134) {$1, 3, 4$};
  \node[state, right=of 134] (25) {$2, 5$};
  \node[state, right=of 25] (13) {$1, 3$};
  \node[state, below=of 13] (2) {$2$};
  \node[state, below=of 25] (6) {$6$};
  \node[state, below=of 0] (es) {$\emptyset$};
  \node[state, accepting, right=of 13] (f) {$q_1$};

  \path (i) edge node {$1$} (0);
  \path (i) edge[bend left=60, show control points] node[above, pos=0.2] {$1$} (f);
  \path (0) edge node {$a$} (134);
  \path (0) edge node {$b$} (es);
  \path (0) edge[bend left=45, show control points] node {$1$} (f);
  \path (134) edge[loop below] node[above] {$a$} (134);
  \path (134) edge node {$b$} (25);
  \path (25) edge node {$a$} (13);
  \path (25) edge node {$b$} (6);
  \path (25) edge[bend left, show control points] node {$1$} (f);
  \path (13) edge[bend right=45, show control points] node {$a$} (134);
  \path (13) edge node {$b$} (2);
  \path (2) edge[bend left, show control points] node {$a$} (13);
  \path (2) edge[bend left, show control points] node[above] {$b$} (es);
  \path (2) edge node[pos=0.75] {$1$} (f);
  \path (6) edge node {$a$} (134);
  \path (6) edge node {$b$} (es);
  \path (es) edge[loop left, show control points] node {$a, b$} (es);
  \path (es) edge[bend right=70, show control points] node[pos=0.1, below] {$1$} (f);
  \end{tikzpicture}
\end{document}

...and compares the output with the whitespace mentioned in the question: The control points are exactly at the edge of the picture

I still haven't found a solution to this without the manual fiddling suggested by Ignasi (see Is there a way to control whitespace around a TikZ picture?).

JPW
  • 721