7

I have a number of figures coming from experiments; they are indexed with an integer number, and they are not always consecutive. Given a list of the indexes, I need to put them in a tabular of, say, 4 columns. After some searching I made this:

\begin{table}[H]
\begin{tabular}{|c|c|c|c|}
\hline

\newcounter{imagecounter}

\foreach \n in {2,3,10,11,13,14,16,17,18,19,24,25,26,31,32,33,34,35,39,40}{
\stepcounter{imagecounter}
\ifnum\intcalcMod{\value{imagecounter}}{4}=0
& \includegraphics{image_index\n.png} \\
\fi
\ifnum\intcalcMod{\value{imagecounter}}{4}=1
\includegraphics{image_index\n.png} 
\fi
\ifnum\intcalcMod{\value{imagecounter}}{4}=2
& \includegraphics{image_index\n.png} 
\fi
\ifnum\intcalcMod{\value{imagecounter}}{4}=3
& \includegraphics{image_index\n.png} 
\fi
}
\end{tabular}
\end{table}

The problem is that, apparently, IF controllers must be inside tabular cells (is that the case?). I haven't been able to solve it or to find an alternative.

Is there a simple way to solve it? Is there another approach?

If so, please provide an example, I am very new to macros, new commands, and anything that is not straightforwards formatting text and tables.

1
  • please include a compilable example; for example \intcalcMod is a macro we can guess but it is not part of standard latex.
    – user4686
    Mar 20, 2015 at 16:01

3 Answers 3

3

Here is the more or less standard way if one really wants to use \foreach inside the tabular.

(edit extends the code to cover the case where the number of images is not a multiple of the number of columns)

I followed suit and used an \intcalcMod macro but it is more economical not to use anything like this but rather reset to zero the image counter after each row. This alternative is added next.

\documentclass[border=12pt]{standalone}

\usepackage{pgffor}
\newcommand*{\intcalcMod}[2]{\numexpr #1+#2-((#1+(#2/2))/#2)*#2\relax}
\newcounter{imagecounter}
\usepackage{graphicx}

\begin{document}
  \begin{tabular}{|l|l|l|l|}
    \hline
    \def\TEMP {}%
      \foreach \n in 
        {2,3,10,11,13,14,16,17,18,19,24,25,26,31,32,33,34,35,39,40}%
      {\stepcounter{imagecounter}%
       \xdef\TEMP {\unexpanded\expandafter{\TEMP}\noexpand 
                   \includegraphics[width=2cm]{example-image.png}%
                   (\n)}% (put it in the filename for the final version)
       \ifnum\intcalcMod{\value{imagecounter}}{4}=0
          \expandafter\gdef\expandafter\TEMP\expandafter{\TEMP \\}%
       \else
          \expandafter\gdef\expandafter\TEMP\expandafter{\TEMP &}%
       \fi
       }%
    \TEMP
% added for the case the total number of images is not multiple of 4
    \ifnum\intcalcMod{\value{imagecounter}}{4}=0
     \else\expandafter\\
    \fi
%
    \hline
  \end{tabular}
\end{document}

Better not to use any \intcalcMod whatever it is:

    \hline
    \def\TEMP {}%
      \foreach \n in 
        {2,3,10,11,13,14,16,17,18,19,24,25,26,31,32,33,34,35,39,40}%
      {\stepcounter{imagecounter}%
       \xdef\TEMP {\unexpanded\expandafter{\TEMP}\noexpand 
                   \includegraphics[width=2cm]{example-image.png}%
                   (\n)}% (put it in the filename for the final version)
       \ifnum\value{imagecounter}=4
          \expandafter\gdef\expandafter\TEMP\expandafter{\TEMP \\}%
          \setcounter{imagecounter}{0}%
       \else
          \expandafter\gdef\expandafter\TEMP\expandafter{\TEMP &}%
       \fi
       }%
    \TEMP
    \ifnum\value{imagecounter}=0
     \else\expandafter\\
    \fi
%
    \hline

enter image description here

0
1

Another one assuming that you can use TikZ anyway and again you have multiples of 4 ( because it gives an indexerror with the PGF array lookup which can be fixed by testing the actual number of images at the start).

\documentclass[tikz]{standalone}
\usetikzlibrary{matrix}
\def\imarray{{2,3,10,11,13,14,16,17,18,19,24,25,26,31,32,33,34,35,39,40}}
\def\TEMP{}
\foreach\x in {1,...,5}{% Row num, just guessing. 
  \foreach\y[evaluate={\mynum= {\imarray[int((\x-1)*4+\y-1)]};}
    ] in {1,...,4}{%Col num 4 given
      \xdef\TEMP{\expandafter\unexpanded\expandafter{\TEMP}%
      \noexpand\node{\noexpand\includegraphics[width=2cm]{example-image} (\mynum)};%
      \ifnum\y=4 \noexpand\\\else\noexpand\&\fi%
    }%
  }%
}

\begin{document}
\begin{tikzpicture}
\matrix[ampersand replacement=\&] (m) {\TEMP};
\end{tikzpicture}
\end{document}

enter image description here

And we tried to collect this topic under Appending active and expansion sensitive characters to a macro

1

I'd use expl3, that allows several features:

\documentclass{article}
\usepackage{graphicx}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\loopimages}{O{}m}
 {% #1 is a list of options, #2 is the list of numbers
  \leon_loopimages:nn { #1 } { #2 }
 }

\keys_define:nn { leon/loopimages }
 {
  name .tl_set:N = \l_leon_loop_name_tl,
  columns .int_set:N = \l_leon_loop_columns_int,
  columns .initial:n = 4,
  padding .dim_set:N = \l_leon_loop_padding_dim,
  padding .initial:n = 1em,
  last .choice:,
  last/center .code:n = \tl_set:Nn \l_leon_loop_align_tl { \centering },
  last/flush  .code:n = \tl_set:Nn \l_leon_loop_align_tl { \raggedright },
  last .initial:n = flush,
  leading .dim_set:N = \l_leon_loop_leading_dim,
  leading .initial:n = 1ex,
 }

\dim_new:N \l_leon_loop_width_dim

\cs_new_protected:Npn \leon_loopimages:nn #1 #2
 {
  \group_begin:
  \keys_set:nn { leon/loopimages } { #1 }
  \dim_set:Nn \l_leon_loop_width_dim
   {
    (
     \columnwidth - 
     \l_leon_loop_padding_dim * (\l_leon_loop_columns_int - 1)
    ) / \l_leon_loop_columns_int
   }
  \par % be in vertical mode
  \dim_set_eq:NN \lineskip \l_leon_loop_leading_dim
  \tl_use:N \l_leon_loop_align_tl % alignment
  \clist_map_inline:nn { #2 }
   {
    \includegraphics[width=\l_leon_loop_width_dim]{\l_leon_loop_name_tl ##1}
    \hspace{\l_leon_loop_padding_dim}
   }
  \par
  \group_end:
 }

\ExplSyntaxOff

\begin{document}

\begin{figure}[htp]

\loopimages[
  name=image_index,
]{2,3,10,11,13,14,16,17}

\caption{Some images}

\end{figure}

\begin{figure}[htp]

\loopimages[
  name=image_index,
  columns=5,
  last=center,
]{2,3,10,11,13,14,16,17}

\caption{Some images}

\end{figure}

\begin{figure}[htp]

\loopimages[
  name=image_index,
  columns=5,
  last=flush,
]{2,3,10,11,13,14,16,17}

\caption{Some images}

\end{figure}

\end{document}

The allowed keys are:

  • name for the common part in the file names (this should of course be always present)

  • columns to tell how many columns we want (default 4)

  • last with value either center or flush (default) for telling how the last row will be set

  • padding to set the space between the columns (default 1em)

  • leading to set the vertical space between rows (default 1ex)

The mandatory argument to \loopimages is the list of indices.

enter image description here

The code computes the image width: we divide the column width by the number of columns after having subtracted the padding between columns. An \hspace is inserted between two images.

You must log in to answer this question.

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