[Tex/LaTex] How to horizontally top-align multiple \tikzpicture’s without using \hspace

horizontal alignmentspacingtikz-pgf

The use case I'm having is the following:

\documentclass{article}

\usepackage{amsmath}
\usepackage[showframe]{geometry}
\usepackage{qtree}

\begin{document}

\Tree [.A B C [.D E ] ]
\Tree [.F [.G H ] I ]
\Tree [.J [.K [.L M M ] N ] O ]
\Tree [.F [.G H ] I ]

\end{document}

which due to qtrees clever horizontal alignment produces

qtree

Now, as qtree is limited to 5 branches, I'm using tikz-qtree and therefore essentially a tikzpicture:

\documentclass{article}

\usepackage{amsmath}    
\usepackage[showframe]{geometry}    
\usepackage{tikz}
\usepackage{tikz-qtree}

\begin{document}

\begin{center}
\begin{tikzpicture}
    \Tree [.A B C [.D E ] ]
\end{tikzpicture}
\begin{tikzpicture}
    \Tree [.F [.G H ] I ]
\end{tikzpicture}
\begin{tikzpicture}
    \Tree [.J [.K [.L M M ] N ] O ]
\end{tikzpicture}
\begin{tikzpicture}
    \Tree [.F [.G H ] I ]
\end{tikzpicture}
\end{center}

\end{document}

which produces

tikz-qtree

How can I achieve the same spacing as in qtree? So that each space between two tikzpictures and to the borders is the same, without using any manual measurements. Also, alignment should be at the top, not bottom.

Best Answer

If you have many TikZ pictures you want align at the top you can use the align at top style defined as

\tikzset{align at top/.style={baseline=(current bounding box.north)}}

The \Tree macros of tikz-qtree check whether they are already in a PGF picture so you could simply write

\Tree [.A B C [.D E ] ]
\Tree [.F [.G H ] I ]
\Tree [.J [.K [.L M M ] N ] O ]
\Tree [.F [.G H ] I ]

and they would automatically align at the top.

But they are not spread along the horizontal space.

The alignment can be fixed by including \hfills between the \Trees/the TikZ pictures. An additional \hfill is needed before the first and the last element.

To save typing I have introduced a environment spreadTrees that adds a \hfillbefore every PGF/TikZ picture and appends a last \hfill\null at the end of the environment. The center environment is included, though actually only needed for the vertical space the environment includes.

You can do the same without the center environment (for floats). This is what the spreadTrees* environment does. There is a slight different horizontal placement, though.

\hspace*{\fill} instead of \hfill\null

Here’s the definition of the environments according to the comment by Ignasi and the answer by egreg:

\newenvironment{spreadTrees}{%
    \expandafter\def\expandafter\pgfpicture\expandafter{\expandafter\hfill\pgfpicture}%
    \center}{\hspace*{\fill}\par\endcenter}

\newenvironment{spreadTrees*}{%
    %\noindent % (if not only used inside floats)
    \expandafter\def\expandafter\pgfpicture\expandafter{\expandafter\hfill\pgfpicture}%
}{\hspace*{\fill}}

Code

\documentclass{article}
\usepackage[showframe]{geometry}
\usepackage{tikz}
\usepackage{tikz-qtree}

\newenvironment{spreadTrees}{%
    \expandafter\def\expandafter\pgfpicture\expandafter{\expandafter\hfill\pgfpicture}%
    \center}{\hfill\null\endcenter}
\newenvironment{spreadTrees*}{%
    %\noindent % (if not only used inside floats)
    \expandafter\def\expandafter\pgfpicture\expandafter{\expandafter\hfill\pgfpicture}%
}{\hfill\null}

\begin{document}%
\begin{spreadTrees}
\Tree [.A B C [.D E ] ]
\Tree [.F [.G H ] I ]
\Tree [.J [.K [.L M M ] N ] O ]
\Tree [.F [.G H ] I ]
\end{spreadTrees}

\hrule

\begin{figure}[h]
\begin{spreadTrees*}
\Tree [.A B C [.D E ] ]
\Tree [.F [.G H ] I ]
\Tree [.J [.K [.L M M ] N ] O ]
\Tree [.F [.G H ] I ]
\end{spreadTrees*}
\caption{(Figure above)}
\end{figure}
\end{document}

Output

enter image description here