tikz: double lines are shifted

Status-by-design.

When TikZ works out how much a path contributes to a picture, it does its best to ensure that the entire visible path is included in the resulting box. As the actual path is done by the renderer, it has to do some guesswork to figure out exactly how big the box should be. Moreover, it isn't always easy to compute the actual bounding box (bézier curves being a case in point). Once it has an idea of the bounding box for the actual path, that still might not be enough because the path is only the infinitesimal path and the visible path has width. Since these measurements are, by their nature, somewhat crude, PGF simply adds half the line width to each side of the bounding box to take into account this extra part.

One way to see this in action is to repeat each drawing with the additional option line cap=rect. This extends the line by half the line width at each end, but doesn't change the bounding box because the potential for this extension has already been taken into account by the sizing mechanism.

If you want to force a particular bounding box you should specify it beforehand with the \useasboundingbox command.

\documentclass[12pt]{article}
%\url{http://tex.stackexchange.com/q/130456/86}
\usepackage{tikz}
\begin{document}
\begin{tabular}{ll}
\fbox{\tikz[baseline=-0.5ex]\draw[thick](0,0)--(3ex,0);}&test\\
\fbox{\tikz[baseline=-0.5ex]\draw[thick,line cap=rect](0,0)--(3ex,0);}&test\\
\fbox{\tikz[baseline=-0.5ex]\draw[thick,double](0,0)--(3ex,0);}&test\\ 
\fbox{\tikz[baseline=-0.5ex]\draw[thick,double,line cap=rect](0,0)--(3ex,0);}&test\\ 
\fbox{\tikz[baseline=-0.5ex]\draw[thick,line width=2.2pt](0,0)--(3ex,0);}&test\\
\fbox{\tikz[baseline=-0.5ex]\draw[thick,line width=2.2pt,line cap=rect](0,0)--(3ex,0);}&test\\
\fbox{\tikz[baseline=-0.5ex]\draw[thick,double](0,0)--(3ex,0);}&test\\ 
\fbox{\tikz[baseline=-0.5ex]\draw[thick,double,line cap=rect](0,0)--(3ex,0);}&test\\ 
\end{tabular}

\end{document}

Width of tikzpictures

So while one could classify this as undesired behaviour, to get it absolutely right would take more computation than I suspect PGF wants to do and certainly more than most people want!


Update 2013-08-29 Here's a straightforward way to achieve what (I think) you want: that only coordinates are used for computing the bounding box and not line width. It uses the fact that the two parts that you want to separate are already separated in the code: the coordinates are processed as the path is built up, and as the path is built then the bounding box is continually adjusted accordingly, but the linewidth is added to the bounding box only when the path is used. So the following inserts some code in between the path being built and the path being used to turn off the computation of the bounding box. There is already a hook to insert code at the relevant point: the \tikz@addmode command, and updating the bounding box is determined by the condition \ifpgf@relevantforpicturesize.

\documentclass{article}
%\url{http://tex.stackexchange.com/q/130456/86}
\usepackage{tikz}

\makeatletter
\tikzset{
  only coordinates are relevant/.is choice,
  only coordinates are relevant/.default=true,
  only coordinates are relevant/true/.code={%
    \tikz@addmode{\pgf@relevantforpicturesizefalse}},
  only coordinates are relevant/false/.code={%
    \tikz@addmode{\pgf@relevantforpicturesizetrue}}
}
\makeatother

\begin{document}
\begin{tikzpicture}
\draw[line width=1cm,red,only coordinates are relevant] (0,0) rectangle (5,5);
\draw (current bounding box.south east) rectangle (current bounding box.north west);
\end{tikzpicture}
\end{document}

Screenshot:

Only coordinates relevant for picture size

It might need a little tweaking to make it work with pre- and post-actions: I haven't tested it extensively.


It is actually the internal box padding creating the illusion, if you keep the paths but do the drawing later then the problem disappears which supports the diagnosis about internal box padding depends on the aspect ratio (what?) line width. If I make the line width of single line equal to the double then we get proper alignment.

I agree that this can be considered as a bug. Again, a temporary fix can be issuing the paths without drawing but overlaying the actual drawings on top. Both are given below.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\tikzset{every picture/.style={
           baseline=-0.5ex,
           show background rectangle,
           %execute at begin picture={},
           %execute at end picture={}
     }
 }
\begin{document}
\begin{tabular}{ll}
\tikz{\draw[line width=2.2pt](0,0)--(3ex,0);}&test\\
\tikz{\draw[thick,double](0,0)--(3ex,0);}&test\\
\tikz{\path[postaction={overlay, double,draw,thick}](0,0)--(3ex,0);}&test\\
\tikz{\path[postaction={overlay, draw, thick}](0,0)--(3ex,0);}&test 
\end{tabular}
\end{document}

enter image description here

Tags:

Tikz Pgf