TikZ: How to center captions below figures in matrix

One possibility would be to name some appropriate nodes in each cell of the first row, then use the fit library to build some framing nodes and finally place the captions with respect to these new nodes:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{fit,positioning}

\begin{document}
\begin{tikzpicture}[grow=right]
  \matrix[column sep=1cm] {
    \node (R1)  {X};
    \node (P1) [right=45pt of R1] {P};
    \draw (R1) to (P1);
    \node[inner sep=0pt,fit= (R1) (P1)]  (box1) {}; &
    \node (root) {A} child { node (child) {P} } ;
    \node[inner sep=0pt,fit= (root) (child)]  (box2) {};
    &
    \node (lroot) {X}
      child { node {R} }
      child { node {R}
        child { node {A} }
        child { node {A}
          child { node {P} }
          child { node (lchild) {P} }
          child { node {P} }
        }
        child { node {A} }
      }
      child { node {R} }
    ;
    \node[inner sep=0pt,fit= (lroot) (lchild)]  (box3) {};
    \\
    \node[below=of box1.center] {caption}; & \node[below=of box2.center] {other caption}; & \node[below=of box3.center] {more caption};
    \\
  };
\end{tikzpicture}
\end{document}

enter image description here


It seems to me that your tikzpictures can actually be separated since there's no co-dependence between them. As such, I would use the subcaption package's subfigure environment as follows.

screenshot

The idea is one that I have used quite a few times before:

  • measure the biggest picture
  • then use its height to justify the smaller pictures vertically.

Here's the complete MWE:

% arara: pdflatex
% !arara: indent: {overwrite: true}
\documentclass{article}
\usepackage{geometry}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usepackage{subcaption}
\newsavebox{\tempbox}

\begin{document}

% store the biggest picture
% so that we can measure it
\sbox{\tempbox}{%
    \begin{tikzpicture}[grow=right]
        \node {X}
        child { node {R} }
        child { node {R}
            child { node {A} }
            child { node {A}
                child { node {P} }
                child { node {P} }
                child { node {P} }
            }
            child { node {A} }
        }
        child { node {R} };
    \end{tikzpicture}%
}

\begin{figure}[!htb]
    \centering
    \begin{subfigure}{.33\textwidth}
        \centering
        \vbox to\ht\tempbox{%
            \vfill
            \begin{tikzpicture}[grow=right]
                \node (R1)  {X};
                \node (P1) [right=45pt of R1] {P};
                \draw (R1) to (P1);
            \end{tikzpicture}
            \vfill
        }
        \caption{caption}
    \end{subfigure}%
    \begin{subfigure}{.33\textwidth}
        \centering
        \vbox to\ht\tempbox{%
            \vfill
            \begin{tikzpicture}[grow=right]
                \node {A} child { node {P} } ;
            \end{tikzpicture}
            \vfill
        }
        \caption{other caption}
    \end{subfigure}%
    \begin{subfigure}{.33\textwidth}
        \centering
        % use the save box
        \usebox{\tempbox}
        \caption{more caption}
    \end{subfigure}
\end{figure}
\end{document}

A) With three tikzpicture environments and without matrix

This way seems to work : three figures are aligned with the option baseline and captions are placed inside the code with (current bounding box.base)

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}

\begin{tikzpicture}[baseline]
    \node (R1)  {X};
    \node (P1) [right=45pt of R1] {P};
    \draw (R1) to (P1);
    \node[below=2cm] at (current bounding box.base) {caption 1};
\end{tikzpicture}
\hfill
\begin{tikzpicture}[grow=right,baseline]
    \node {A} child { node {P} } ;
    \node[below=2cm] at (current bounding box.base) {caption 2};
\end{tikzpicture}
\hfill
\begin{tikzpicture}[grow=right,baseline]
    \node {X}
      child { node {R} }
      child { node {R}
        child { node {A} }
        child { node {A}
          child { node {P} }
          child { node {P} }
          child { node {P} }
        }
        child { node {A} }
      }
      child { node {R} } ;
    \node[below=2cm] at (current bounding box.base) {caption 3};
\end{tikzpicture}

\end{document}

enter image description here

B) One tikzpicture environment with three scope environments and a matrix

We get the same result

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}

\begin{document}
\begin{tikzpicture}
\matrix[column sep=2cm] {   
\begin{scope}[baseline]
    \node (R1)  {X};
    \node (P1) [right=45pt of R1] {P};
    \draw (R1) to (P1);
    \node[below=2cm] at (current bounding box.base) {caption 1};
\end{scope}
&
\begin{scope}[grow=right,baseline]
    \node {A} child { node {P} } ;
    \node[below=2cm] at (current bounding box.base) {caption 2};
\end{scope}
&
\begin{scope}[grow=right,baseline]
    \node {X}
      child { node {R} }
      child { node {R}
        child { node {A} }
        child { node {A}
          child { node {P} }
          child { node {P} }
          child { node {P} }
        }
        child { node {A} }
      }
      child { node {R} } ;
    \node[below=2cm] at (current bounding box.base) {caption 3};
\end{scope}
\\};
\end{tikzpicture}
\end{document}