[Tex/LaTex] pgfplotsforeachungrouped in groupplot

foreachpgfplots

I want to create a grid of plots with groupplots, where every plot is taken from an external file and included via pgfplots.

Due to the fact, that foreach doesn't work nicely in a axis environment, I switched to pgfplotsforeachungrouped. To workaround the fact, that macros are expanded at the end, I put my definitions in \edef\temp{\noexpand...}; \temp constructs.

My problem is, that in my nested loops, only the first iteration is executed as expected. The restriction on nested loops does also forbid the use of \pgfplotsinvokeforeach because this macro doesn't support nested loops yet.

My grid is defined by the variables x and y. It should follow the following scheme on the left, but results in the middle scheme for the title and the right scheme for the plot.

expected:                       actual result (title):          actual result (plot):
(1,1) (2,1) (3,1)               (1,1) (2,1) (3,1)               (1,1) (1,1) (1,1)
(1,2) (2,2) (3,2)               (1,2) (2,1) (3,1)               (1,1) (1,1) (1,1)
(1,3) (2,3) (3,3)               (1,3) (2,1) (3,1)               (1,1) (1,1) (1,1)
(1,4) (2,4) (3,4)               (1,4) (2,1) (3,1)               (1,1) (1,1) (1,1)

How can I get this grid automatically?


According source (as a prerequisite, you would need the files field_y_x.png with y and x going from 1 to 3 and 1 to 4, respectively):

\documentclass{scrartcl}

\usepackage{tikz}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}
\pgfplotsset{compat=newest}

\begin{document}

\begin{tikzpicture}
    \begin{groupplot}[
        width=0.3\textwidth,
        height=0.3\textwidth,
        xmin=-0.6,
        xmax=0.6,
        ymin=-0.6,
        ymax=0.6,
        zmin=-0.6,
        zmax=0.6,
        group style = {group size = 3 by 4,
                           horizontal sep = 2cm,
                           vertical sep = 2cm
                           }
        ]       

        \pgfplotsforeachungrouped \nx in {1,2,3,4}%
        {
            \pgfplotsforeachungrouped \ny in {1,2,3}%
            {
                \edef\mytitle{\noexpand\nextgroupplot[title=\ny-\nx];};
                \mytitle
                \edef\temp{\noexpand\addplot3 graphics[%
                    points={% important
                        (-0.7,-0.7, 0.7) => ( 641,1000-51)
                        (-0.7, 0.7,-1.5) => ( 904,1000-538)
                        (-0.7,-0.7,-1.5) => ( 641,1000-765)
                        ( 0.7,-0.7,-1.5) => (1096,1000-897)
                        }] {field_\ny_\nx.png};};
                \temp
            }
        }

    \end{groupplot}
\end{tikzpicture}

\end{document}

Best Answer

I stumbled upon this when trying to setup a huge plot page with three nested loops.

I think your problem is solvable by replacing the first loop statement

\pgfplotsforeachungrouped \nx in {1,2,3,4}%

by

\pgfplotsinvokeforeach{1,2,3,4}%

At least here (without the actual files field_\nx_\ny.png and without knowing what they contain and what you want to plot), it does not admonish missing files anymore (I only created \nx={1,2} and \ny={1,2} for testing for this error message). Also, the titles are then correct.

I did not look into the code of pgfplots but something must prevent \pgfplotsforeachungrouped from being usable in nesting. Probably there is some temporary macro name involved which is overwritten by the inner loop.

Note that this fix does not help me, i.e. if you have more than two nested loops: as you correctly stated, so far \pgfplotsinvokeforeach cannot be nested.

Having written and posted all this, I googled some more: This question seems rather similar to this one Changing parameters in a groupplot : In short, use package etoolbox which provides a macro \eappto to build up a chain of macros.

UPDATE

To wrap this up, I add example code for doing three nested loops with etoolbox. So, have the following within pgfplot's axis environment:

\def\myPlots{}%
\pgfplotsforeachungrouped \myk in {1,2,4,10}{%
    \pgfplotsforeachungrouped \myr in {1,2,4}{%
        \eappto\myPlots{%
            \noexpand\nextgroupplot[title = {$k=\myk, p=\myr$}]
        }
        \pgfplotsforeachungrouped \myseed in {420,...,429}{
            \eappto\myPlots{%
                \noexpand\addplot+[no marks] table[x=iteration,y=residual,col sep=comma] {somedatafile_k\myk_r\myr_seed\myseed.dat};
                \noexpand\addlegendentry{\myseed};
            }
        }
    }
}
\myPlots
Related Question