2

I'm trying to use tikz to illustrate an iterative process in figures, but when placed next to each other, the different heights of the images cause the captions to become unaligned, as below: Unaligned Captions

Unfortunately, there doesn't exist a way to change the height of a tikz picture without altering the scale of the content in the picture (as far as I can tell), and causing the alignment to be aligned at the bottom causes a dissociation in the same object between pictures:

Unaligned Figures

Is there any way I can do what I want to do? Preferably without manually adding vertical whitespace and fiddling with the values until it looks close.

Here is my current example:

\begin{figure}[ht!]
    \centering
    \begin{subfigure}[b]{0.4\textwidth}
        \begin{tikzpicture}
            \draw [red, dashed, fill = red, fill opacity = 0.2] (0,0) circle (2.5);
            \draw [blue!50!cyan, dashed, ultra thick, fill = blue!50!cyan, fill opacity = 0.5] 
                plot [smooth cycle, tension=1, domain=0:320, samples=18] (\x:{2+rand/2});

            \foreach \x in {-3,...,3}
            \foreach \y in {-3,...,3}
            {
                \fill (\x,\y) circle (1pt);
            }

            \draw [decorate, decoration={brace, amplitude = 5pt, mirror, raise = 3pt}] (2,-3) -- (3,-3) node [midway, below, yshift = -8pt] {$\varepsilon$};

            \node at (2.5, 1.6) {$B_y(R)$};
            \node at (.5, .5) {$A$};
        \end{tikzpicture}
        \caption{$A$ and $B_y(R)$ overlaid by $\mathcal G_\varepsilon$}
    \end{subfigure}
    \begin{subfigure}[b]{0.4\textwidth}
        \begin{tikzpicture}
            \draw [red, dashed, fill = red, fill opacity = 0.2] (0,0) circle (2.5);
            \draw [blue!50!cyan, dashed, ultra thick, fill = blue!50!cyan, fill opacity = 0.5] 
                plot [smooth cycle, tension=1, domain=0:320, samples=18] (\x:{2+rand/2});

            %  Only clip things in here
            \begin{scope}
                \clip circle (2.5);
                \foreach \x in {-3,...,3}
                \foreach \y in {-3,...,3}
                {
                    \fill (\x,\y) circle (1pt);
                }
            \end{scope}


            \draw [decorate, decoration={brace, amplitude = 5pt, mirror, raise = 3pt}] (0,-2) -- (1,-2) node [midway, below, yshift = -8pt] {$\varepsilon$};

            \node at (2.5, 1.6) {$B_y(R)$};
            \node at (.5, .5) {$A$};
        \end{tikzpicture}
        \caption{$A$ and $B_y(R)$ overlaid by $\mathcal G'_\varepsilon$}
    \end{subfigure}
\end{figure}

3 Answers 3

1

Here is a way to do it with the subfloatrow environment from floatrow:

\documentclass{report}
\usepackage{geometry}
\usepackage{caption, subcaption, floatrow}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing}

\begin{document}

\begin{figure}[ht!]
    \centering
    \begin{subfigure}[b]{0.4\textwidth}
        \begin{tikzpicture}
            \draw [red, dashed, fill = red, fill opacity = 0.2] (0,0) circle (2.5);
            \draw [blue!50!cyan, dashed, ultra thick, fill = blue!50!cyan, fill opacity = 0.5]
                plot [smooth cycle, tension=1, domain=0:320, samples=18] (\x:{2+rand/2});

            \foreach \x in {-3,...,3}
            \foreach \y in {-3,...,3}
            {
                \fill (\x,\y) circle (1pt);
            }

            \draw [decorate, decoration={brace, amplitude = 5pt, mirror, raise = 3pt}] (2,-3) -- (3,-3) node [midway, below, yshift = -8pt] {$\varepsilon$};

            \node at (2.5, 1.6) {$B_y(R)$};
            \node at (.5, .5) {$A$};
        \end{tikzpicture}
        \caption{$A$ and $B_y(R)$ overlaid by $\mathcal G_\varepsilon$}
    \end{subfigure}
    \begin{subfigure}[b]{0.4\textwidth}
        \begin{tikzpicture}
            \draw [red, dashed, fill = red, fill opacity = 0.2] (0,0) circle (2.5);
            \draw [blue!50!cyan, dashed, ultra thick, fill = blue!50!cyan, fill opacity = 0.5]
                plot [smooth cycle, tension=1, domain=0:320, samples=18] (\x:{2+rand/2});

            % Only clip things in here
            \begin{scope}
                \clip circle (2.5);
                \foreach \x in {-3,...,3}
                \foreach \y in {-3,...,3}
                {
                    \fill (\x,\y) circle (1pt);
                }
            \end{scope}


            \draw [decorate, decoration={brace, amplitude = 5pt, mirror, raise = 3pt}] (0,-2) -- (1,-2) node [midway, below, yshift = -8pt] {$\varepsilon$};

            \node at (2.5, 1.6) {$B_y(R)$};
            \node at (.5, .5) {$A$};
        \end{tikzpicture}
        \caption{$A$ and $B_y(R)$ overlaid by $\mathcal G'_\varepsilon$}
    \end{subfigure}
\end{figure}

\newpage

\begin{figure}[ht!]
    \centering
\floatsetup{valign=c, heightadjust = object}
\begin{subfloatrow}
    \centering
\quad \ffigbox[\FBwidth]{
       \fbox{\begin{tikzpicture}
            \draw [red, dashed, fill = red, fill opacity = 0.2] (0,0) circle (2.5);
            \draw [blue!50!cyan, dashed, ultra thick, fill = blue!50!cyan, fill opacity = 0.5]
                plot [smooth cycle, tension=1, domain=0:320, samples=18] (\x:{2+rand/2});

            \foreach \x in {-3,...,3}
            \foreach \y in {-3,...,3}
            {
                \fill (\x,\y) circle (1pt);
            }

            \draw [decorate, decoration={brace, amplitude = 5pt, mirror, raise = 3pt}] (2,-3) -- (3,-3) node [midway, below, yshift = -8pt] {$\varepsilon$};

            \node at (2.5, 1.6) {$B_y(R)$};
            \node at (.5, .5) {$A$};
        \end{tikzpicture}}}
        {\caption{$A$ and $B_y(R)$ overlaid by $\mathcal G_\varepsilon$}}
\hskip 48pt
    \ffigbox[\FBwidth]
       {\fbox{\begin{tikzpicture}
            \draw [red, dashed, fill = red, fill opacity = 0.2] (0,0) circle (2.5);
            \draw [blue!50!cyan, dashed, ultra thick, fill = blue!50!cyan, fill opacity = 0.5]
                plot [smooth cycle, tension=1, domain=0:320, samples=18] (\x:{2+rand/2});

            % Only clip things in here
            \begin{scope}
                \clip circle (2.5);
                \foreach \x in {-3,...,3}
                \foreach \y in {-3,...,3}
                {
                    \fill (\x,\y) circle (1pt);
                }
            \end{scope}


            \draw [decorate, decoration={brace, amplitude = 5pt, mirror, raise = 3pt}] (0,-2) -- (1,-2) node [midway, below, yshift = -8pt] {$\varepsilon$};

            \node at (2.5, 1.6) {$B_y(R)$};
            \node at (.5, .5) {$A$};
        \end{tikzpicture}}}
        {\caption{$A$ and $B_y(R)$ overlaid by $\mathcal G'_\varepsilon$}}
\null
\end{subfloatrow}
\end{figure}

\end{document} 

enter image description here

1
  • Interestingly enough, this does exactly what I was looking for, however use of the subfloatrow environment causes LaTeX to complain that a variety of control sequences (such as \centering and \ffigbox) don't exist, but they still work in the output. Apr 26, 2019 at 20:03
0

You can put the tikzpictures into two minipages and use the subfigures for the captions.

enter image description here

\documentclass{article}
\usepackage{geometry}
\usepackage{tikz}
\usepackage{subcaption}
\usetikzlibrary{decorations.pathreplacing}
\begin{document}

\begin{figure}[ht!]
    \centering
    \begin{minipage}[c]{0.45\textwidth}
        \begin{tikzpicture}
            \draw [red, dashed, fill = red, fill opacity = 0.2] (0,0) circle (2.5);
            \draw [blue!50!cyan, dashed, ultra thick, fill = blue!50!cyan, fill opacity = 0.5] 
                plot [smooth cycle, tension=1, domain=0:320, samples=18] (\x:{2+rand/2});

            \foreach \x in {-3,...,3}
            \foreach \y in {-3,...,3}
            {
                \fill (\x,\y) circle (1pt);
            }

            \draw [decorate, decoration={brace, amplitude = 5pt, mirror, raise = 3pt}] (2,-3) -- (3,-3) node [midway, below, yshift = -8pt] {$\varepsilon$};

            \node at (2.5, 1.6) {$B_y(R)$};
            \node at (.5, .5) {$A$};
        \end{tikzpicture}
    \end{minipage} \quad\quad
    \begin{minipage}[c]{0.45\textwidth}
        \begin{tikzpicture}
            \draw [red, dashed, fill = red, fill opacity = 0.2] (0,0) circle (2.5);
            \draw [blue!50!cyan, dashed, ultra thick, fill = blue!50!cyan, fill opacity = 0.5] 
                plot [smooth cycle, tension=1, domain=0:320, samples=18] (\x:{2+rand/2});

            %  Only clip things in here
            \begin{scope}
                \clip circle (2.5);
                \foreach \x in {-3,...,3}
                \foreach \y in {-3,...,3}
                {
                    \fill (\x,\y) circle (1pt);
                }
            \end{scope}


            \draw [decorate, decoration={brace, amplitude = 5pt, mirror, raise = 3pt}] (0,-2) -- (1,-2) node [midway, below, yshift = -8pt] {$\varepsilon$};

            \node at (2.5, 1.6) {$B_y(R)$};
            \node at (.5, .5) {$A$};
        \end{tikzpicture}
    \end{minipage}
    \begin{subfigure}{0.45\textwidth}
              \caption{$A$ and $B_y(R)$ overlaid by $\mathcal G_\varepsilon$}
    \end{subfigure}\quad\quad
    \begin{subfigure}{0.45\textwidth}
       \caption{$A$ and $B_y(R)$ overlaid by $\mathcal G'_\varepsilon$}
    \end{subfigure}

\end{figure}

\end{document}
1
  • Adding \centering inside your minipages will better align the figures with their respective captions.
    – erik
    Apr 26, 2019 at 19:45
0

One can save the first bounding box as global macros and reuse it.

\documentclass{article}
\usepackage{geometry}
\usepackage{tikz}
\usepackage{subcaption}
\usetikzlibrary{decorations.pathreplacing}
\begin{document}

\begin{figure}[ht]% Do you really think ! does anything?
    \centering
    \begin{subfigure}[b]{0.4\textwidth}
        \begin{tikzpicture}
            \draw [red, dashed, fill = red, fill opacity = 0.2] (0,0) circle (2.5);
            \draw [blue!50!cyan, dashed, ultra thick, fill = blue!50!cyan, fill opacity = 0.5] 
                plot [smooth cycle, tension=1, domain=0:320, samples=18] (\x:{2+rand/2});

            \foreach \x in {-3,...,3}
            \foreach \y in {-3,...,3}
            {
                \fill (\x,\y) circle (1pt);
            }

            \draw [decorate, decoration={brace, amplitude = 5pt, mirror, raise = 3pt}] (2,-3) -- (3,-3) node [midway, below, yshift = -8pt] {$\varepsilon$};

            \node at (2.5, 1.6) {$B_y(R)$};
            \node at (.5, .5) {$A$};
    % save bounding box as global macros
            \path (current bounding box.south west);
            \pgfgetlastxy{\xleft}{\ybottom}%
            \global\let\xleft=\xleft
            \global\let\ybottom=\ybottom
            \path (current bounding box.north east);
            \pgfgetlastxy{\xright}{\ytop}%
            \global\let\xright=\xright
            \global\let\ytop=\ytop
        \end{tikzpicture}
        \caption{$A$ and $B_y(R)$ overlaid by $\mathcal G_\varepsilon$}
    \end{subfigure}
    \begin{subfigure}[b]{0.4\textwidth}
        \begin{tikzpicture}
            \path (\xleft,\ybottom) (\xright,\ytop);% set bounding box limits
            \draw [red, dashed, fill = red, fill opacity = 0.2] (0,0) circle (2.5);
            \draw [blue!50!cyan, dashed, ultra thick, fill = blue!50!cyan, fill opacity = 0.5] 
                plot [smooth cycle, tension=1, domain=0:320, samples=18] (\x:{2+rand/2});

            %  Only clip things in here
            \begin{scope}
                \clip circle (2.5);
                \foreach \x in {-3,...,3}
                \foreach \y in {-3,...,3}
                {
                    \fill (\x,\y) circle (1pt);
                }
            \end{scope}


            \draw [decorate, decoration={brace, amplitude = 5pt, mirror, raise = 3pt}] (0,-2) -- (1,-2) node [midway, below, yshift = -8pt] {$\varepsilon$};

            \node at (2.5, 1.6) {$B_y(R)$};
            \node at (.5, .5) {$A$};
        \end{tikzpicture}
        \caption{$A$ and $B_y(R)$ overlaid by $\mathcal G'_\varepsilon$}
    \end{subfigure}\hfil
\end{figure}
\end{document}

demo

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .