Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I have several very similar images except some have some extra graphics that enlarge them slightly. This causes some pictures to be offset and not aligned visually when it's clear they should be.

How can I align several tikzpictures along the the same origin they were created and center vertically and horizontally properly?

  • First, I want to align the 3 large boxes regardless of the what the small boxes are doing

  • Second, I want to be able to center them all without adding additional spaces the \begin{center} seems to do

  • Third, I want to be able to reproduce the exact same results but everything in landscape mode without using the landscape package if possible. (as you can see, the problem is that TeX is putting one rectangle at a time which is not what I want)

  • The methods should be easy and quick. I have many rectangles stacked and some need to be grouped arbitrarily. What these means is I want the methods to sort of be "smart" in that they can figure out themselves so I don't have to go change a lot of stuff each time I have to change the grouping. Basically I would like the first rectangle on the page to define the alignment location and the others on the same page to use it unless I tell them not to.

I've tried creating a custom bounding box as shown in How does TiKZ calculate positioning of picture on page? but it didn't do anything unless I make it too large which then causes other problems. (I can end up doing the alignment but it seems more complex than necessary)

\documentclass[10pt]{book}
\usepackage{tikz}

\begin{document}
\begin{tikzpicture}
    \draw[line width=30pt] (0,0) -- (7,0);
\end{tikzpicture}

\begin{tikzpicture}
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
\end{tikzpicture}

\begin{tikzpicture}
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
    \draw[line width=20pt] (-0.8, 0) -- (-0.5, 0);
\end{tikzpicture}



\begin{center}%
\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (7,0);
\end{tikzpicture}%
\end{center}%

\begin{center}%
\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
\end{tikzpicture}%
\end{center}%

\begin{center}%
\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
    \draw[line width=20pt] (-0.8, 0) -- (-0.5, 0);
\end{tikzpicture}%
\end{center}%




\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (0,7);
\end{tikzpicture}%


\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (0,7);
    \draw[line width=20pt] (0,-0.4) -- (0,-0.1);
\end{tikzpicture}%

\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (0,7);
    \draw[line width=20pt] (0,-0.4) -- (0,-0.1);
    \draw[line width=20pt] (0,-0.8) -- (0,-0.5);
\end{tikzpicture}%



\begin{center}%
\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (0,7);
\end{tikzpicture}%
\end{center}


\begin{center}%
\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (0,7);
    \draw[line width=20pt] (0,-0.4) -- (0,-0.1);
\end{tikzpicture}%
\end{center}%


\begin{center}%
\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (0,7);
    \draw[line width=20pt] (0,-0.4) -- (0,-0.1);
    \draw[line width=20pt] (0,-0.8) -- (0,-0.5);
\end{tikzpicture}%
\end{center}%


\end{document}
share|improve this question
    
About the centering issue: The center environment is more for text paragraphs and will add the vertical space because of this. The \centering macro should be used for figure and such because of this. It can be grouped using \begingroup .. \engroup if required. A paragraph break (\par) before the \engroup might also be a good idea. An alternative is \adjustbox{center=<width>}{..} (adjustbox package), which centers the content by adding white space to the left and right. The <width> value is optional and default to the text width. –  Martin Scharrer Mar 29 '12 at 6:51
1  
You could align your tikzpictures by placing them into \nodes of a parent tikzpicture which can then be aligned using the usual TikZ settings. Alternatively enlarge the bounding box of every picture manually so that it is always identical. A technique like this is used in Centering a TikZ picture around an area BTW, (semi-)automatic placement and alignment is rather difficult to achieve with multiple pictures. –  Martin Scharrer Mar 29 '12 at 6:56
    
@MartinScharrer You know that it is heresy to suggest nesting TikZ pictures, don't you? (tex.stackexchange.com/q/46818/86) –  Loop Space Mar 29 '12 at 7:09
    
@AndrewStacey: It has indeed its drawbacks, but for alignment only it should be fine. Main problem is mostly that style settings of the outer picture can effect the inner pictures. This can be avoided by storing these in boxes beforehand. –  Martin Scharrer Mar 29 '12 at 7:21
    
I second Martin's suggestion of looking at that question about centring a TikZ picture around an area. One route to answering this would be to ensure that the bounding box was of such a size that the right elements were aligned. If that doesn't look suitable, may I ask how you would like to tell TikZ which elements of the secondary picture should be aligned? Do you want to put a key on the specific path, or would specifying a particular coordinate (say as an argument to the picture) be better? –  Loop Space Mar 29 '12 at 8:17
show 1 more comment

2 Answers 2

up vote 8 down vote accepted

For getting the horizontal alignment right, you could supply the trim left option to the tikzpictures, which sets the bounding box so it starts at x=0. There's no option like that for the vertical alignment, however, so in that case you'll have to make sure the bounding boxes between the pictures match by setting them manually using \pgfresetboundingbox and then issuing a \path command that has the right dimensions.

You can automate this by defining a style like

master/.style={
    execute at end picture={
        \coordinate (lower right) at (current bounding box.south east);
        \coordinate (upper left) at (current bounding box.north west);
    }
}

which you supply to the first picture of a group to save the necessary bounding box information, and

slave/.style={
    execute at end picture={
        \pgfresetboundingbox
        \path (upper left) rectangle (lower right);
    }
}

which you supply to the other pictures in the group to set their bounding box to be equal to that of the first picture.

You have to be a bit careful with manually adjusted bounding boxes, as the pictures could protrude into the page margins or into the surrounding text.

\documentclass[10pt]{book}
\usepackage{tikz}

\tikzset{
    master/.style={
        execute at end picture={
            \coordinate (lower right) at (current bounding box.south east);
            \coordinate (upper left) at (current bounding box.north west);
        }
    },
    slave/.style={
        execute at end picture={
            \pgfresetboundingbox
            \path (upper left) rectangle (lower right);
        }
    }
}


\begin{document}
\begin{tikzpicture}[master]
    \draw[line width=30pt] (0,0) -- (7,0);
\end{tikzpicture}

\begin{tikzpicture}[slave]
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
\end{tikzpicture}

\begin{tikzpicture}[slave]
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
    \draw[line width=20pt] (-0.8, 0) -- (-0.5, 0);
\end{tikzpicture}



\begin{center}%
\begin{tikzpicture}[master]%
    \draw[line width=30pt] (0,0) -- (7,0);
\end{tikzpicture}%
\end{center}%

\begin{center}%
\begin{tikzpicture}[slave]%
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
\end{tikzpicture}%
\end{center}%

\begin{center}%
\begin{tikzpicture}[slave]%
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
    \draw[line width=20pt] (-0.8, 0) -- (-0.5, 0);
\end{tikzpicture}%
\end{center}%




\begin{tikzpicture}[master]%
    \draw[line width=30pt] (0,0) -- (0,7);

\end{tikzpicture}%
\hspace{1em}
\begin{tikzpicture}[slave]%
    \draw[line width=30pt] (0,0) -- (0,7);
    \draw[line width=20pt] (0,-0.4) -- (0,-0.1);
\end{tikzpicture}%
\hspace{1em}
\begin{tikzpicture}[slave]%
    \draw[line width=30pt] (0,0) -- (0,7);
    \draw[line width=20pt] (0,-0.4) -- (0,-0.1);
    \draw[line width=20pt] (0,-0.8) -- (0,-0.5);

\end{tikzpicture}%



\begin{center}%
\begin{tikzpicture}[master]%
    \draw[line width=30pt] (0,0) -- (0,7);
\end{tikzpicture}%
\hspace{1em}
\begin{tikzpicture}[slave]%
    \draw[line width=30pt] (0,0) -- (0,7);
    \draw[line width=20pt] (0,-0.4) -- (0,-0.1);
\end{tikzpicture}%
\hspace{1em}
\begin{tikzpicture}[slave]%
    \draw[line width=30pt] (0,0) -- (0,7);
    \draw[line width=20pt] (0,-0.4) -- (0,-0.1);
    \draw[line width=20pt] (0,-0.8) -- (0,-0.5);
\end{tikzpicture}%
\end{center}%


\end{document}
share|improve this answer
    
This seems easy enough although it would be nice not have to set a master and slaves and just use the first in a group as the master. I'd rather have an environment that wraps the pictures than anything. Is it possible to create one that sort of adds the master and slave to the enclosed tikzpictures? –  Uiy Mar 29 '12 at 12:46
    
@Uiy: Yes, that is possible. –  Jake Mar 29 '12 at 14:13
    
For extra glory, I think it would be good to be able to separate horizontal and vertical adjustments. I can imagine that when doing the horizontal alignments, one wants the vertical to be dealt with as usual so that the diagrams take up the right amount of space on the page. –  Loop Space Mar 29 '12 at 18:23
add comment

This is another method.

\documentclass{article}
\usepackage{tikz}
\usepackage[margin=2cm,showframe]{geometry}
%------------------------------------------
\begin{document}
\begingroup
\centering
\begin{minipage}[c]{.5\textwidth}
  \flushright
%------------------------------------------
\begin{tikzpicture}
    \draw[line width=30pt] (0,0) -- (7,0);
\end{tikzpicture}\\
%------------------------------------------
\begin{tikzpicture}
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
\end{tikzpicture}\\
%------------------------------------------
\begin{tikzpicture}
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
    \draw[line width=20pt] (-0.8, 0) -- (-0.5, 0);
\end{tikzpicture}\\
%------------------------------------------
\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (7,0);
\end{tikzpicture}\\%
%------------------------------------------
\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
\end{tikzpicture}\\%
%------------------------------------------
\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
    \draw[line width=20pt] (-0.8, 0) -- (-0.5, 0);
\end{tikzpicture}
%------------------------------------------
\end{minipage}
\vfil
%%%====================================
\rotatebox{90}{
\begin{minipage}[c]{.5\textwidth}
  \flushright
%------------------------------------------
\begin{tikzpicture}
    \draw[line width=30pt] (0,0) -- (7,0);
\end{tikzpicture}\\
%------------------------------------------
\begin{tikzpicture}
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
\end{tikzpicture}\\
%------------------------------------------
\begin{tikzpicture}
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
    \draw[line width=20pt] (-0.8, 0) -- (-0.5, 0);
\end{tikzpicture}\\
%------------------------------------------
\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (7,0);
\end{tikzpicture}\\%
%------------------------------------------
\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
\end{tikzpicture}\\%
%------------------------------------------
\begin{tikzpicture}%
    \draw[line width=30pt] (0,0) -- (7,0);
    \draw[line width=20pt] (-0.4, 0) -- (-0.1, 0);
    \draw[line width=20pt] (-0.8, 0) -- (-0.5, 0);
\end{tikzpicture}
%------------------------------------------
 \end{minipage}}\par
\endgroup
%------------------------------------------
\end{document}

enter image description here

The length of the code can be reduced by making use of \savebox since they are same figures with a different rotation.

share|improve this answer
    
The results look very nice and exactly what I want to see. I'm not sure if it's as simple as I would like though ;/ Jake's method seems to be easier but doens't get the results I would like. –  Uiy Mar 29 '12 at 12:08
    
@Uiy, It is simple. It involves only a minipage and rotatebox. –  Harish Kumar Mar 29 '12 at 15:01
    
The problem is that if I change the groups then I have to do a lot of copying and pasting... and if I have a couple of hundred of these then it easily is to much work. I do like the results though and there might many other alternatives. –  Uiy Mar 29 '12 at 15:10
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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