Iteration in LaTeX
Asked Answered
C

3

81

I would like to use some iteration control flow to simplify the following LaTeX code.

  \begin{sidewaystable}
  \caption{A glance of images}
  \centering
  \begin{tabular}{| c ||c| c| c |c| c|| c |c| c|c|c| }
  \hline
  \backslashbox{Theme}{Class} &\multicolumn{5}{|c|}{Class 0} & \multicolumn{5}{|c|}{Class 1}  \\
  \hline

  \hline
          1 &
          \includegraphics[scale=2]{../../results/1/0_1.eps}
          &\includegraphics[scale=2]{../../results/1/0_2.eps}
          &\includegraphics[scale=2]{../../results/1/0_3.eps}
          &\includegraphics[scale=2]{../../results/1/0_4.eps}
          &\includegraphics[scale=2]{../../results/1/0_5.eps}
          &\includegraphics[scale=2]{../../results/1/1_1.eps}
          &\includegraphics[scale=2]{../../results/1/1_2.eps}
          &\includegraphics[scale=2]{../../results/1/1_3.eps}
          &\includegraphics[scale=2]{../../results/1/1_4.eps}
          &\includegraphics[scale=2]{../../results/1/1_5.eps}      \\
  \hline

  ...  % similarly for 2, 3, ..., 22

  \hline
          23 &
          \includegraphics[scale=2]{../../results/23/0_1.eps}
          &\includegraphics[scale=2]{../../results/23/0_2.eps}
          &\includegraphics[scale=2]{../../results/23/0_3.eps}
          &\includegraphics[scale=2]{../../results/23/0_4.eps}
          &\includegraphics[scale=2]{../../results/23/0_5.eps}
          &\includegraphics[scale=2]{../../results/23/1_1.eps}
          &\includegraphics[scale=2]{../../results/23/1_2.eps}
          &\includegraphics[scale=2]{../../results/23/1_3.eps}
          &\includegraphics[scale=2]{../../results/23/1_4.eps}
          &\includegraphics[scale=2]{../../results/23/1_5.eps}      \\
  \hline

  \end{tabular}
  \end{sidewaystable}

I learn that the forloop package provides the for loop. But I am not sure how to apply it to my case? Or other methods not by forloop?


If I also want to simply another similar case, where the only difference is that the directory does not run from 1, 2, to 23, but in some arbitrary order such as 3, 2, 6, 9,..., or even a list of strings such as dira, dirc, dird, dirb,.... How do I make the LaTeX code into loops then?

Cultivar answered 1/4, 2010 at 16:3 Comment(1)
please check if the accepted answer is still the best choice. The highest voted answer has almost three times as many up votes! Thanks.Barometer
G
33

Something like this will take care of the body of your tabular:

\newcounter{themenumber}
\newcounter{classnumber}
\newcounter{imagenumber}
\forloop{themenumber}{1}{\value{themenumber} < 24}{
    % \hline <-- Error here
    \arabic{themenumber}
    \forloop{classnumber}{0}{\value{classnumber} < 2}{
        \forloop{imagenumber}{1}{\value{imagenumber} < 6}{
            & \includegraphics[scale=2]{
                ../../results/\arabic{themenumber}/\arabic{classnumber}_\arabic{imagenumber}.eps
            }
        }
    }
    \\
    \hline
}

I had to comment out the first \hline because it gave me an error:

You can't use `\hrule' here except with leaders.

I'm not sure what that means; if you really cannot live without the double line, I can look into it more.

Also note that you have to use <; for example, <= 24 will not work.


As to your update: I would simply declare a command that takes the argument that you're looping over. Something like this:

\newcommand\fordir[1]{do something complex involving directory named #1}

\fordir{dira}
\fordir{dirb}
\fordir{dirc}
\dots
Gilbertson answered 1/4, 2010 at 16:27 Comment(2)
Is the forloop command built-in?Patently
No, it's from the forloop package as stated in the question.Gilbertson
D
155

You may use pgffor package, a tool provided by pgf. The basic syntax is:

\foreach \n in {0,...,22}{do something}

Notably, this for loop is not restricted to integers, for example:

\foreach \n in {apples,burgers,cake}{Let's eat \n.\par}
Demandant answered 11/5, 2011 at 2:39 Comment(1)
For some reason, I get a compilation error when importing the package pgffor.Bis
G
33

Something like this will take care of the body of your tabular:

\newcounter{themenumber}
\newcounter{classnumber}
\newcounter{imagenumber}
\forloop{themenumber}{1}{\value{themenumber} < 24}{
    % \hline <-- Error here
    \arabic{themenumber}
    \forloop{classnumber}{0}{\value{classnumber} < 2}{
        \forloop{imagenumber}{1}{\value{imagenumber} < 6}{
            & \includegraphics[scale=2]{
                ../../results/\arabic{themenumber}/\arabic{classnumber}_\arabic{imagenumber}.eps
            }
        }
    }
    \\
    \hline
}

I had to comment out the first \hline because it gave me an error:

You can't use `\hrule' here except with leaders.

I'm not sure what that means; if you really cannot live without the double line, I can look into it more.

Also note that you have to use <; for example, <= 24 will not work.


As to your update: I would simply declare a command that takes the argument that you're looping over. Something like this:

\newcommand\fordir[1]{do something complex involving directory named #1}

\fordir{dira}
\fordir{dirb}
\fordir{dirc}
\dots
Gilbertson answered 1/4, 2010 at 16:27 Comment(2)
Is the forloop command built-in?Patently
No, it's from the forloop package as stated in the question.Gilbertson
M
1

Loop through figures

You can simplify your code by first importing the pgffor package in your preamble and then using the following code.

\foreach \i in {1,...,5}{
     \begin{figure}[htb!]
         \centering
         \includegraphics[width=.5\linewidth]{figures/figure\i}
         \caption{Caption \i}\label{fig:figure\i}
     \end{figure}

}

Nested loops

You can also have two for loops one nested inside the other:

\foreach \i in {1,...,5}{
     \foreach \x in {1,...,5}{
         \begin{figure}[htb!]
             \centering
             \includegraphics[width=.5\linewidth]{figures/figure\x_\i}
              \caption{Caption \x \i}\label{fig:figure\x_\i}
         \end{figure}
     }
}

multido package

Alternatively, you can also do the same with the multido package. The syntax is a bit different but the result is the same.

\multido{\i=1+1}{3}{%
    \begin{figure}[htb!]
        \centering
        \includegraphics[width=.5\linewidth]{figures/figure\i}
        \caption{Caption \i}\label{fig:figure\i}
    \end{figure}
}

Adding subfigures with a custom caption

If for each figure you also want to specify a unique caption you can do that using the following code. Since the example below uses subfigures please import the following packages in your preamble \usepackage{caption,subcaption,graphicx}

\def\names{{figure1/my caption for figure 1},{figure2/caption2},{figure3/caption3},{test/my caption}}

\begin{figure}
    \foreach \name/\subcap in \names {%
     \begin{subfigure}[p]{0.47\textwidth}
         \includegraphics[width=\linewidth]{figures/\name}
         \caption{\subcap}
     \end{subfigure}\quad
    }
    \caption{Main figure caption}\label{fig:subfig_2}
\end{figure}

In this video tutorial I provide many more examples and I cover this topic more in detail.

Mutant answered 17/4 at 8:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.