Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I want a 2x2 scatterplot matrix of the data in the file scatter.dat:

0.5334437   0.4824717
0.6848940   0.6865826
0.5818373   0.6335347
0.5465202   0.5290712

The following code works:

\begin{tikzpicture}
  \pgfplotstableread{scatter.dat}\myscatter
  \begin{groupplot}[
      group style={
        group size=2 by 2,
        horizontal sep=0pt, vertical sep=0pt,
        xticklabels at=edge bottom,yticklabels at=edge left},
      height=3.5cm,width=3.5cm,
    ]

    \nextgroupplot
    \addplot+[only marks] table[header=false,x index=0,y index=0] {\myscatter};
    \nextgroupplot
    \addplot+[only marks] table[header=false,x index=0,y index=1] {\myscatter};
    \nextgroupplot
    \addplot+[only marks] table[header=false,x index=1,y index=0] {\myscatter};
    \nextgroupplot
    \addplot+[only marks] table[header=false,x index=1,y index=1] {\myscatter};
  \end{groupplot}
\end{tikzpicture}

I would prefer an automatic version with loops for larger scatter plot matrices by modifying the code from above as follows:

\begin{tikzpicture}
  \pgfplotstableread{scatter.dat}\myscatter
  \begin{groupplot}[
      group style={
        group size=2 by 2,
        horizontal sep=0pt, vertical sep=0pt,
        xticklabels at=edge bottom,yticklabels at=edge left},
      height=3.5cm,width=3.5cm,
    ]

    \foreach \columnA in {0,...,1} {
      \foreach \columnB in {0,...,1} {
        \nextgroupplot
        \addplot+[only marks] 
          table[header=false,x index=\columnA,y index=\columnB]
          {\myscatter};
      }
    }
  \end{groupplot}
\end{tikzpicture}

However, compiling this code with pdflatex yields the following error:

! Illegal unit of measure (pt inserted).
<to be read again>
share|improve this question
add comment

1 Answer

up vote 5 down vote accepted

Update: A much more elegant way is to make use of the fact that the groupplots library knows the current row and column and the total number of plots. The counters have to be made available first by defining new names without@:

\documentclass{article}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}

\begin{document}

\makeatletter
\newcommand{\currentrow}{\the\pgfplots@group@current@row}
\newcommand{\currentcolumn}{\the\pgfplots@group@current@column}
\newcommand{\totalplots}{\pgfplots@group@totalplots}
\makeatother

\begin{tikzpicture}
  \pgfplotstableread{scatter.dat}\myscatter
  \begin{groupplot}[
      group style={
        group size=2 by 2,
        horizontal sep=0pt, vertical sep=0pt,
        xticklabels at=edge bottom,yticklabels at=edge left},
      height=5cm,width=5cm,xmin=0.5
    ]


    \pgfplotsinvokeforeach{1,...,\totalplots} {
    \nextgroupplot
    \pgfmathsetmacro\x{\currentcolumn-1}
    \pgfmathsetmacro\y{\currentrow-1}

        \addplot+[only marks] 
          table[header=false,x index=\x,y index=\y]
          {\myscatter};
    }
  \end{groupplot}
\end{tikzpicture}

\end{document}

The way without the groupplots counters:

In this case you need to use \pgfplotsinvokeforeach{<list>}{<commands>} to make sure that the looping variable is passed to the commands expanded, otherwise all commands end up executing with the same value of the looping variable. Unfortunately, \pgfplotsinvokeforeach can not be nested, so you need to make do with a single looping variable that you split up inside the loop.

In my code below, you just need to adjust the values of variables \a and \b if you need other setups. It's not quite as intuitive as the nested loops, but it works.

\documentclass{article}
\usepackage{pgfplots}
\usepgfplotslibrary{groupplots}

\begin{document}

\begin{tikzpicture}
  \pgfplotstableread{scatter.dat}\myscatter
  \begin{groupplot}[
      group style={
        group size=2 by 2,
        horizontal sep=0pt, vertical sep=0pt,
        xticklabels at=edge bottom,yticklabels at=edge left},
      height=5cm,width=5cm
    ]
\pgfmathsetmacro\a{2}
\pgfmathsetmacro\b{2}
\pgfmathsetmacro\c{\a+\b}

    \pgfplotsinvokeforeach{1,...,\c} {
    \nextgroupplot
    \pgfmathsetmacro\x{mod(#1-1,\a)}
    \pgfmathsetmacro\y{floor((#1-1)/\b)}

        \addplot+[only marks] 
          table[header=false,x index=\x,y index=\y]
          {\myscatter};
    }
  \end{groupplot}
\end{tikzpicture}

\end{document}

scatterplots with pgfplotsinvokeforeach

share|improve this answer
    
Thanks, the error disappeared! I can see the scatter plot matrix having 2 by 2 scatterplots. The scatterplot matrix is almost perfect except of the data shown: Every plot shows the correlation of the first column to itself. It seams that \columnA and \columnB are 0 all the time. –  Christoph Apr 6 '11 at 12:14
    
@Chris: Ah yes, sorry for that, you need \pgfplotsinvokeforeach in this case. I've changed my answer. –  Jake Apr 6 '11 at 14:23
    
For LaTeX Beamer you will need [fragile]. –  Christoph Apr 7 '11 at 4:06
    
The way without the groupplots counters arranges the scatterplots in wrong order for largar scattor plot matrices than 2 by 2. –  Christoph Apr 7 '11 at 4:16
    
@Chris: Thanks again. Fixed now. –  Jake Apr 7 '11 at 5:14
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.