10

following up on this Vertical icons between subfloats problem, I'm struggling now adding horizontal (e.g. from left to right or from right to left) to my subfloats

This is what I have so far:

\documentclass{report}
\usepackage{pifont}
\usepackage[svgnames, x11names]{xcolor}
\usepackage{graphicx
}
\usepackage{caption}
\usepackage{subfig}
\usepackage{tabularx}
\newcommand\bigleftArrow{\color{Tomato2}\rotatebox[origin=c]{180}{\scalebox{2.4}[3.6]{\ding{225}}}}
\newcommand\bigrightArrow{\color{Tomato2}\rotatebox[origin=c]{0}{\scalebox{2.4}[3.6]{\ding{225}}}}
\begin{document}

\begin{figure} [h]
\begin{tabularx}{\textwidth}{@{}*{5}{>{\centering\arraybackslash}X}@{}}
  \subfloat[text 1]{
     \includegraphics[width=0.28\textwidth]
     {example-image-a}}
      &
      \bigleftArrow
      &
  \subfloat[text 2]{
     \includegraphics[width=0.28\textwidth]
     {example-image-b}}
      &
      \bigleftArrow
      &
  \subfloat[text 3]{
     \includegraphics[width=0.28\textwidth]
     {example-image-c}}
     \\
  \subfloat[text 4]{
     \includegraphics[width=0.28\textwidth]
     {example-image}}
       &
       \bigrightArrow
      &
  \subfloat[text 5]{
     \includegraphics[width=0.28\textwidth]
     {example-image}}
      &
      \bigrightArrow
      &
  \subfloat[text 6]{
     \includegraphics[width=0.28\textwidth]
     {example-image}}
\end{tabularx}
  \captionof{figure}[]{long text}
  \label{fig:merge}
\end{figure}

\end{document} 

which gives me this:

enter image description here

But obviously I would like to have the icons centered vertical and horizontal between the images e.g. between (a) and (b) (and not between the image captions)

Any suggestions?


This it how it should look like (roughly :D )

enter image description here


UPDATE

both so far provided answers are working pretty good. But I discovered a issue if one caption is longer than the others like provided for in the following for figure (c). The whole image moves up (insted of the regular behaviour where the text box grows to the bottom). I even amended how it should appear (Now: 1x 3 images; 1x 2 images connected with arrows) Here is the amended code with the little issue:

\documentclass{report}
\usepackage{pifont}
\usepackage[svgnames, x11names]{xcolor}
\usepackage{graphicx
}
\usepackage{caption}
\usepackage{subfig}
\usepackage{tabularx}

%% Fix Vertical Alignment
\renewcommand{\tabularxcolumn}[1]{>{\small}m{#1}} 

% Add \hspace to arrow definition
\newcommand\bigleftArrow{\hspace{40pt}\color{green}\rotatebox[origin=c]{180}{\scalebox{2.4}[3.6]{\ding{225}}}} 
\newcommand\bigrightArrow{\hspace{40pt}\color{green}\rotatebox[origin=c]{0}{\scalebox{2.4}[3.6]{\ding{225}}}}



\begin{document}

\begin{figure} [h]
\begin{tabularx}{\textwidth}{@{}*{5}{>{\centering\arraybackslash}X}@{}}
  \subfloat[text 1]{
     \includegraphics[width=0.28\textwidth]
     {example-image-a}}
      &
      \bigrightArrow
      &
  \subfloat[text 2]{
     \includegraphics[width=0.28\textwidth]
     {example-image-b}}
      &
      \bigrightArrow
      &
  \subfloat[text 3 is longer than the others: text text text text text text text text text]{
     \includegraphics[width=0.28\textwidth]
     {example-image-c}}
     \\
  \subfloat[text 4]{
     \includegraphics[width=0.28\textwidth]
     {example-image}}
      &
      &
       \bigrightArrow
      &
      &
  \subfloat[text 6]{
     \includegraphics[width=0.28\textwidth]
     {example-image}}
\end{tabularx}
  \captionof{figure}[]{long text}
  \label{fig:merge}
\end{figure}

\end{document} 

And this is how its drawn. (note image (c)/text 3 and the red lines I draw on to it):

enter image description here

7 Answers 7

8
+50

I would like to show you a couple of solutions with a tikz matrix.

I've added a yshift to your \bigleftArrow and \bigrightArrow commands to refine the vertical alignment of the arrows.

To avoid the Underfull \hbox you could use \centering within your \subcaption command.

\documentclass{report}
\usepackage{pifont}
\usepackage[x11names]{xcolor}
\usepackage{graphicx}
\usepackage{subcaption}
\usepackage{tikz}
\usetikzlibrary{matrix}

\newcommand*{\bigrightArrow}{|[yshift=-2]| \color{green}{\scalebox{2.4}[3.6]{\ding{225}}}}
\newcommand*{\bigleftArrow}{|[yshift=2]| \color{Tomato2}{\rotatebox[origin=c]{180}{\scalebox{2.4}[3.6]{\ding{225}}}}}

\begin{document}
    \begin{figure}
        \centering
        \begin{tikzpicture}
        \matrix[matrix of nodes, 
        nodes={anchor=center},
        column sep=-3.7em]{%
            \includegraphics[width=0.26\textwidth]{example-image-a}
            &
            \bigrightArrow
            &
            \includegraphics[width=0.26\textwidth]{example-image-b}
            &
            \bigrightArrow
            &
            \includegraphics[width=0.26\textwidth]{example-image-c}
            \\
            \begin{minipage}[t][10ex][t]{0.26\textwidth}
            \subcaption{text 1\label{fig:1amerge2}}
            \end{minipage}
            &&
            \begin{minipage}[t][10ex][t]{0.26\textwidth}
            \subcaption{text 2}
            \end{minipage}%
            &&
            \begin{minipage}[t][10ex][t]{0.26\textwidth}
            \subcaption{\centering text 3 is longer than the others: text text text text text text text text text}
            \end{minipage}%
            \\[4pt]
            &
            \includegraphics[width=0.26\textwidth]{example-image}
            &
            \bigleftArrow
            &
            \includegraphics[width=0.26\textwidth]{example-image}
            \\
            &
            \begin{minipage}[t]{0.26\textwidth}
            \subcaption{text 4}
            \end{minipage}%
            &&
            \begin{minipage}[t]{0.26\textwidth}
            \subcaption{text 6}
            \end{minipage}%
            \\
        };
        \end{tikzpicture}
        \caption{long text\label{fig:merge2}}
    \end{figure}
    \begin{figure}
        \centering
        \begin{tikzpicture}
        \matrix[matrix of nodes, 
                nodes={anchor=center},
                column sep=-3pt
                ]{%
            \includegraphics[width=0.26\textwidth]{example-image-a}
            &
            \bigrightArrow
            &
            \includegraphics[width=0.26\textwidth]{example-image-b}
            &
            \bigrightArrow
            &
            \includegraphics[width=0.26\textwidth]{example-image-c}
            \\
            \begin{minipage}[t][10ex][t]{0.26\textwidth}
            \subcaption{text 1\label{fig:1a}}
            \end{minipage}
            &&
            \begin{minipage}[t][10ex][t]{0.26\textwidth}
            \subcaption{text 2}
            \end{minipage}%
            &&
            \begin{minipage}[t][10ex][t]{0.26\textwidth}
            \subcaption{text 3 is longer than the others: text text text text text text text text text}
            \end{minipage}%
            \\[4pt]
            \includegraphics[width=0.26\textwidth]{example-image}
            &&
            \bigleftArrow
            &&
            \includegraphics[width=0.26\textwidth]{example-image}
            \\
            \begin{minipage}[t]{0.26\textwidth}
            \subcaption{text 4}
            \end{minipage}%
            &&&&
            \begin{minipage}[t]{0.26\textwidth}
            \subcaption{text 6}
            \end{minipage}%
            \\
        };
        \end{tikzpicture}
        \caption{long text\label{fig:merge}}
    \end{figure}
\end{document}

enter image description here

11

It's not clear you need a table at all:

enter image description here

\documentclass{report}
\usepackage{pifont}
\usepackage[svgnames, x11names]{xcolor}
\usepackage{graphicx
}
\usepackage{caption}
\usepackage{subfig}
\usepackage[export]{adjustbox}


% Add \hspace to arrow definition
\newcommand\bigleftArrow{\textcolor{green}{\rotatebox[origin=c]{180}{\scalebox{2.4}[3.6]{\ding{225}}}}}
\newcommand\bigrightArrow{\hspace*{.2em}\textcolor{green}{\rotatebox[origin=c]{0}{\scalebox{2.4}[3.6]{\ding{225}}}}}



\begin{document}

\begin{figure} [ht]
  \subfloat[text 1]{
     \includegraphics[width=0.28\textwidth,valign=m]
     {example-image-a}}
      \hfill
      \bigrightArrow
      \hfill
  \subfloat[text 2]{
     \includegraphics[width=0.28\textwidth,valign=m]
     {example-image-b}}
      \hfill
      \bigrightArrow
      \hfill
  \subfloat[text 3 is longer than the others: text text text text text text text text text]{
     \includegraphics[width=0.28\textwidth,valign=m]
     {example-image-c}}

  \subfloat[text 4]{
     \includegraphics[width=0.28\textwidth,valign=m]
     {example-image}}
      \hfill
       \bigrightArrow
      \hfill
        \subfloat[text 6]{
     \includegraphics[width=0.28\textwidth,valign=m]
     {example-image}}

  \caption{long text}
  \label{fig:merge}
\end{figure}

\end{document} 
1
  • \usepackage[export]{adjustbox} and valign=m are the secret of this answer. Commented Jan 28, 2022 at 0:54
9

If you use \subcaptionbox from subcaption, the alignment of the captions gets taken care of. The alignment of the arrows is more problematic because there is no automatic way - using this general approach - of figuring out where they should go. So, short of doing things substantially differently, I suggest manually adjusting the vertical position of the arrows. (The horizontal alignment is not a problem.)

For example,

\documentclass{report}
\usepackage{pifont}
\usepackage[x11names]{xcolor}
\usepackage{graphicx}
\usepackage{subcaption}
\usepackage{tabularx}
\renewcommand{\tabularxcolumn}[1]{>{\small\centering\arraybackslash}p{#1}}
\makeatother
\newcommand*\bigrightArrow[1][0pt]{\color{green}\raisebox{#1}{\scalebox{2.4}[3.6]{\ding{225}}}}
\newcommand*\bigleftArrow[1][0pt]{\color{Tomato2}\raisebox{#1}{\rotatebox[origin=c]{180}{\scalebox{2.4}[3.6]{\ding{225}}}}}
\makeatletter
\begin{document}
\begin{figure}
  \centering
  \begin{tabularx}{\textwidth}{@{}XcXcX@{}}
    \subcaptionbox{text 1}{\includegraphics[width=\linewidth]{example-image-a}}
    &
    \bigrightArrow[15pt]
    &
    \subcaptionbox{text 2}{\includegraphics[width=\linewidth]{example-image-b}}
    &
    \bigrightArrow[15pt]
    &
    \subcaptionbox{text 3 is longer than the others: text text text text text text text text text}{\includegraphics[width=\linewidth]{example-image-c}}
    \\
    \subcaptionbox{text 4}{\includegraphics[width=\linewidth]{example-image}}
    &
    \multicolumn{3}{c}{\bigleftArrow[15pt]}
    &
    \subcaptionbox{text 6}{\includegraphics[width=\linewidth]{example-image}}\\
  \end{tabularx}

  \captionof{figure}[]{long text}
  \label{fig:merge}
\end{figure}

\end{document}

A bit fiddly, but it gives the expected results.

aligned

Note that the original code was producing overfull boxes as the images were simply too large. This in itself is going to screw up the alignment. The current code gives only one bad box, for the long caption. If your captions really look like this, you should set them \raggedright or something rather than justified.

1
  • how does one vertically align the image, and also scale the image? \subcaptionbox{text 2}{\includegraphics[width=\linewidth]{example-image-b}}
    – 3kstc
    Commented Sep 12, 2019 at 1:01
7

Here is a solution with only 3 X columns: I put the arrows between columns with @{\bigleftArrow}. As the two rows have different arrows, this requires two tabularx environments. I took the opportunity to improve the codes for the horizontal arrows, so they're vertically centred.

\documentclass{report}
\usepackage{pifont}
\usepackage[svgnames, x11names]{xcolor}
\usepackage{graphicx}
\usepackage{caption}
\usepackage{subfig}
\usepackage{tabularx}
\newcommand\bigleftArrow{\color{Tomato2}\raisebox{-0.2\height}{\rotatebox[origin=c]{180}{\scalebox{2.4}[3.6]{\ding{225}}}}}
\newcommand\bigrightArrow{\color{Tomato2}\raisebox{-0.38\height}{\scalebox{2.4}[3.6]{\ding{225}}}}

\begin{document}

\begin{figure} [h]
  \renewcommand{\tabularxcolumn}[1]{>{\centering\arraybackslash}m{#1}}
  \begin{tabularx}{\textwidth}{@{}X@{\bigleftArrow}X@{\bigleftArrow}X@{}}
    \subfloat[text 1]{
      \includegraphics[width=0.25\textwidth]
      {example-image-a}}
     &
    \subfloat[text 2]{
      \includegraphics[width=0.25\textwidth]
      {example-image-b}}
     &
    \subfloat[text 3]{
      \includegraphics[width=0.25\textwidth]
      {example-image-c}}
  \end{tabularx}
  \\
  \begin{tabularx}{\textwidth}{@{}X@{\bigrightArrow}X@{\bigrightArrow}X@{}}
    \subfloat[text 4]{
      \includegraphics[width=0.25\textwidth]
      {example-image}}
     &
    \subfloat[text 5]{
      \includegraphics[width=0.25\textwidth]
      {example-image}}
     &
    \subfloat[text 6]{
      \includegraphics[width=0.25\textwidth]
      {example-image}}
  \end{tabularx}
  \captionof{figure}[]{long text}
  \label{fig:merge}
\end{figure}

\end{document} 

enter image description here

2
  • nice approach. But unfortunately this causes the same issue like the other reply. If one caption is longer as all the others, the whole image moves upwards. Any idea how to solve this?
    – flor1an
    Commented Jun 28, 2017 at 15:26
  • @user2798895: I'll try to see that. Probably with floatrow.
    – Bernard
    Commented Jun 28, 2017 at 15:43
5

You could align the arrows vertically as explained here. Then push them to the right position using \hspace

MWE:

\documentclass{report}
\usepackage{pifont}
\usepackage[svgnames, x11names]{xcolor}
\usepackage{graphicx
}
\usepackage{caption}
\usepackage{subfig}
\usepackage{tabularx}

%% Fix Vertical Alignment
\renewcommand{\tabularxcolumn}[1]{>{\small}m{#1}} 

% Add \hspace to arrow definition
\newcommand\bigleftArrow{\hspace{40pt}\color{Tomato2}\rotatebox[origin=c]{180}{\scalebox{2.4}[3.6]{\ding{225}}}} 
\newcommand\bigrightArrow{\hspace{40pt}\color{Tomato2}\rotatebox[origin=c]{0}{\scalebox{2.4}[3.6]{\ding{225}}}}



\begin{document}

\begin{figure} [h]
\begin{tabularx}{\textwidth}{@{}*{5}{>{\centering\arraybackslash}X}@{}}
  \subfloat[text 1]{
     \includegraphics[width=0.28\textwidth]
     {example-image-a}}
      &
      \bigleftArrow
      &
  \subfloat[text 2]{
     \includegraphics[width=0.28\textwidth]
     {example-image-b}}
      &
      \bigleftArrow
      &
  \subfloat[text 3]{
     \includegraphics[width=0.28\textwidth]
     {example-image-c}}
     \\
  \subfloat[text 4]{
     \includegraphics[width=0.28\textwidth]
     {example-image}}
       &
       \bigrightArrow
      &
  \subfloat[text 5]{
     \includegraphics[width=0.28\textwidth]
     {example-image}}
      &
      \bigrightArrow
      &
  \subfloat[text 6]{
     \includegraphics[width=0.28\textwidth]
     {example-image}}
\end{tabularx}
  \captionof{figure}[]{long text}
  \label{fig:merge}
\end{figure}

\end{document} 

And the outcome:enter image description here

There are other options of course, defining cells is one that comes to mind.

3
  • thanks that looks great. But I discovered one small issue. One of the captions is longer (more lines as the other) the whole image spikes out from the alignment (the images are not aligned anymore). Do you know as well how to fix this?
    – flor1an
    Commented Jun 28, 2017 at 13:22
  • I'd have to have a MWE of that as well... how about @Bernard s solution ?
    – Elad Den
    Commented Jun 28, 2017 at 14:31
  • I updated my initial post; Bernards solution is nice as well, but causing the same issue.
    – flor1an
    Commented Jun 28, 2017 at 18:38
5

From TeX primitive point of view you need to do something like this:

\def\vhb#1{\vtop{\hbox{#1}}}
\def\rb#1{\raise.9cm\hbox{#1}}

\begin{figure}[h]
\hbox to\hsize{%
  \vhb{\subfloat[text 1]{\includegraphics[width=0.28\textwidth]{example-image-a}}}%
  \hss \rb\bigrightArrow \hss
  \vhb{\subfloat[text 2]{\includegraphics[width=0.28\textwidth]{example-image-b}}}%
  \hss \rb\bigrightArrow \hss
  \vhb{\subfloat[text 3 is longer as  the others text text text text text]{
     \includegraphics[width=0.28\textwidth]{example-image-c}}}%
}
\hbox to\hsize{%
  \vhb{\subfloat[text 4]{\includegraphics[width=0.28\textwidth]{example-image}}}%
  \hss \rb\bigleftArrow \hss
  \vhb{\subfloat[text 5]{\includegraphics[width=0.28\textwidth]{example-image}}}%
  \hss \rb\bigleftArrow \hss
  \vhb{\subfloat[text 5]{\includegraphics[width=0.28\textwidth]{example-image}}}%
}
  \captionof{figure}[]{long text 1}
  \label{fig:merge}
\end{figure}
2

Here I take the OP's original code and do two things to it:

  1. I take the arrows from their own column and instead overlay them over the image via \stackinset with a negative shift (a "stackoutset" you might call it), which does not disrupt the horizontal extent of the base image,

  2. I make the caption of image (c) multiple lines to demonstrate that long captions have no ill effect.

The MWE:

\documentclass{report}
\usepackage{pifont}
\usepackage[svgnames, x11names]{xcolor}
\usepackage{graphicx
}
\usepackage{caption}
\usepackage{subfig}
\usepackage{tabularx}
\newcommand\bigleftArrow{\color{Tomato2}\rotatebox[origin=c]{180}{\scalebox{2.4}[3.6]{\ding{225}}}}
\newcommand\bigrightArrow{\color{Tomato2}\rotatebox[origin=c]{0}{\scalebox{2.4}[3.6]{\ding{225}}}}
\usepackage{stackengine}
\begin{document}

\begin{figure} [h]
\begin{tabularx}{\textwidth}{@{}*{5}{>{\centering\arraybackslash}X}@{}}
  \subfloat[text 1]{
     \stackinset{r}{-7.5ex}{c}{}{\bigrightArrow}{\includegraphics[width=0.28\textwidth]
     {example-image-a}}}
      &&
  \subfloat[text 2]{
     \stackinset{r}{-7.5ex}{c}{}{\bigrightArrow}{\includegraphics[width=0.28\textwidth]
     {example-image-b}}}
      &&
  \subfloat[text 3 is long enough to cause a linebreak]{
     \includegraphics[width=0.28\textwidth]
     {example-image-c}}
     \\
  \subfloat[text 4]{
     \stackinset{r}{-7.5ex}{c}{}{\bigleftArrow}{\includegraphics[width=0.28\textwidth]
     {example-image}}}
      &&
  \subfloat[text 5]{
     \stackinset{r}{-7.5ex}{c}{}{\bigleftArrow}{\includegraphics[width=0.28\textwidth]
     {example-image}}}
      &&
  \subfloat[text 6]{
     \includegraphics[width=0.28\textwidth]
     {example-image}}
\end{tabularx}
  \captionof{figure}[]{long text}
  \label{fig:merge}
\end{figure}

\end{document} 

enter image description here

You must log in to answer this question.

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