2

I and trying to use foreach loop and pgfmathparse inside axis. But it is giving me an error.

\documentclass[10pt,border=0pt]{standalone}

\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{siunitx}

% Default options for plots
\pgfplotsset{%
    compat=1.12,
    compat/show suggested version=false,
    %tick label style={font=\footnotesize},
    %label style={font=\footnotesize},
    legend style={%
        %draw=none,
        font=\footnotesize,
        at={(0.5,1.0)}, % position of legend
        yshift=3pt,
        anchor=south,
        legend columns=2
        legend cell align=left,
        inner xsep=2pt,
        /tikz/column 2/.style={%
            column sep=4pt, % http://tex.stackexchange.com/questions/80215/two-columns-in-legend-in-pgfplots
        },
        /tikz/column 1/.style={%
            column sep=2pt,
        },
        /tikz/column 3/.style={%
            column sep=2pt,
        },
        nodes={inner xsep=0pt,inner ysep=0pt,text depth=0.15em},
        %nodes={inner xsep=2pt,inner ysep=0pt,text depth=0.15em}, % this added a space after the last text 
    },
}


\begin{document}
\begin{tikzpicture}
\begin{axis}[%
    width=20cm,
    ybar stacked,
    bar width=1cm,
    ylabel={YLABEL},
    symbolic x coords={a,b,c,d,e,f},
    ticks=none,
    %xtick={a,b,c,d,e,f}, % adds legend at ticks
    %enlarge x limits=0.5,
    %enlarge x limits,
    enlarge y limits=0.2,
    nodes near coords,
    font=\footnotesize,
    grid=major,
    after end axis/.code={% http://tex.stackexchange.com/questions/55261/labeling-the-axes-of-my-plot
        \node[below] at (xticklabel cs:0.25) {XXX};
        \node[below] at (xticklabel cs:0.75) {YYY};
    }
]

    \addplot coordinates {(a,5.42) (b,13.4) (c,10.69) (d,10.81) (e,30.31) (f,22.53)};
    \addplot coordinates {(a,0.72) (b,17.87) (c,5) (d,1.40) (e,12.39) (f,5.17)};
    \legend {Downlink,Uplink};

    \foreach \x/\y in {1/a,2/b,3/c,4/a,5/b,6/c)} {%
        \pgfmathsetmacro{\coor}{\x*(0.5/6)}
        \node[draw,anchor=south west] at (rel axis cs:\coor,0.8) {\y};
    };
\end{axis}

\end{tikzpicture}
\end{document}
cacamailg
  • 8,405

1 Answers1

4

The reason for this is described in the manual of pgfplots, under section 8.1 Utility commands. I quote the relevant piece:

Keep in mind that inside of an axis environment, all loop constructions (including custom loops, \foreach and \pgfplotsforeachungrouped) need to be handled with care: loop arguments can only be used in places where they are immediately evaluated; but pgfplots postpones the evaluation of many macros. For example, to loop over something and to generate axis descriptions of the form \node at (axis cs:\i,0.5)...., the loop macro \i will be evaluated in \end{axis} – but at that time, the loop is over and its value is lost. The correct way to handle such an application is to expand the loop variable explicitly. For example:

\pgfplotsforeachungrouped \i/\j in {
1 / a,
2 / b,
3 / c
}{
\edef\temp{\noexpand\node at (axis cs: \i,0.5) {\j};}
% \show\temp % lets TeX show you what \temp contains
\temp
}

The example generates three loop iterations: \i=1, \j=a; then \i=2, j=b; then \i=3, \j=c. Inside of the loop body, it expands them and assigns the result to a macro using an “expanded definition”, \edef. The result no longer contains either \i or \j (since these have been expanded). Then, it invokes the resulting macro. Details about the TEX command \edef and expansion control can be found in the document TeX-programming-notes.pdf which comes with pgfplots.

So using the above construction the loop works:

\documentclass[10pt,border=0pt]{standalone}

\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{siunitx}

% Default options for plots
\pgfplotsset{%
    compat=1.12,
    compat/show suggested version=false,
    %tick label style={font=\footnotesize},
    %label style={font=\footnotesize},
    legend style={%
        %draw=none,
        font=\footnotesize,
        at={(0.5,1.0)}, % position of legend
        yshift=3pt,
        anchor=south,
        legend columns=2
        legend cell align=left,
        inner xsep=2pt,
        /tikz/column 2/.style={%
            column sep=4pt, % http://tex.stackexchange.com/questions/80215/two-columns-in-legend-in-pgfplots
        },
        /tikz/column 1/.style={%
            column sep=2pt,
        },
        /tikz/column 3/.style={%
            column sep=2pt,
        },
        nodes={inner xsep=0pt,inner ysep=0pt,text depth=0.15em},
        %nodes={inner xsep=2pt,inner ysep=0pt,text depth=0.15em}, % this added a space after the last text 
    },
}


\begin{document}
\begin{tikzpicture}
\begin{axis}[%
    width=20cm,
    ybar stacked,
    bar width=1cm,
    ylabel={YLABEL},
    symbolic x coords={a,b,c,d,e,f},
    ticks=none,
    %xtick={a,b,c,d,e,f}, % adds legend at ticks
    %enlarge x limits=0.5,
    %enlarge x limits,
    enlarge y limits=0.2,
    nodes near coords,
    font=\footnotesize,
    grid=major,
    after end axis/.code={% http://tex.stackexchange.com/questions/55261/labeling-the-axes-of-my-plot
        \node[below] at (xticklabel cs:0.25) {XXX};
        \node[below] at (xticklabel cs:0.75) {YYY};
    }
]

    \addplot coordinates {(a,5.42) (b,13.4) (c,10.69) (d,10.81) (e,30.31) (f,22.53)};
    \addplot coordinates {(a,0.72) (b,17.87) (c,5) (d,1.40) (e,12.39) (f,5.17)};
    \legend {Downlink,Uplink};

    \foreach \x/\y in {1/a,2/b,3/c,4/a,5/b,6/c} {%
        \pgfmathsetmacro{\coor}{\x*(0.5/6)}
%        \node[draw,anchor=south west] at (rel axis cs:\coor,0.8) {\y};
        \edef\temp{\noexpand\node at (rel axis cs: \coor,0.8) {\y};}
        \temp
    };
\end{axis}

\end{tikzpicture}
\end{document}
Torbjørn T.
  • 206,688