3

I am trying to position one axis environment centered below another one. However, using

\begin{axis}[name=axis2, below of=axis1.south, anchor=north]

does not work as intended, see image below. A similar attempt using the positioning library and

\begin{axis}[name=axis2, below=of axis1.south, anchor=north]

produces similar wrong results.

What am I missing here? Are the axis anchors somehow determined later and not available at the point where I declare axis2?

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{positioning}

\begin{document}
    \begin{tikzpicture}
    \begin{axis}[name=axis1]
    \addplot table[row sep=crcr] {0 0 \\ 1 1 \\};
    \end{axis}

    \begin{axis}[name=axis2, below of=axis1.south, anchor=north]
    \addplot table[row sep=crcr] {0 1 \\ 1 0 \\};
    \end{axis}
    \end{tikzpicture}
\end{document}

two wrongly aligned axis environments

  • Apparently, just using anchor = north west solves the problem. However, I can't explain why yet. – KersouMan Nov 14 at 14:27
  • @KersouMan yes, but when I set a distance between the two plots using positioning, it breaks again. I would be interested to learn what the reason is... – wimi Nov 14 at 14:33
  • 1
    The axis environment may act like a node (more or less), but it isn't one. That [below of=...] works at all (even with bugs) is surprising. – John Kormylo Nov 14 at 15:08
4

Some objects like pics or axis objects only know their dimensions and anchor positions "too late". A very simple trick to position those is to wrap them in a basic matrix (which does not require the matrix library).

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16} %<- you may want to add this
\usetikzlibrary{positioning}

\begin{document}
    \begin{tikzpicture}
    \matrix{
    \begin{axis}[name=axis1]
    \addplot table[row sep=crcr] {0 0 \\ 1 1 \\};
    \end{axis}\\[1em]

    \begin{axis}[name=axis2]
    \addplot table[row sep=crcr] {0 1 \\ 1 0 \\};
    \end{axis}\\
    };
    \end{tikzpicture}

    \begin{tikzpicture}
    \matrix(axis1){
    \begin{axis}
    \addplot table[row sep=crcr] {0 0 \\ 1 1 \\};
    \end{axis}\\};
    \matrix[below=1cm of axis1](axis2){
    \begin{axis}
    \addplot table[row sep=crcr] {0 1 \\ 1 0 \\};
    \end{axis}\\
    };
    \end{tikzpicture}

\end{document}

For just stacking the plots, it suffices to put them in one matrix.

enter image description here

If you wish to access all the features of positioning, put each axis in an individual matrix.

enter image description here

If you change the code for the second axis to become

 \matrix[below=1cm of axis1.south east](axis2){...

you get

enter image description here

as expected.

I continue debating with myself whether it is worthwhile to copy the relevant parts of the matrix definition (notice that this is the core stuff contained in the pgf module matrix, not in the library of the same name!) to define a wrapper that allows one to use positioning on pic and other objects like axis more easily, but the above is already very simple, so I hesitate.

4

If you are not strict about using positioning library, you can go for using scope.

enter image description here

\documentclass{article}
\usepackage{pgfplots}

\begin{document}
\begin{center}
    \begin{tikzpicture}
    \begin{scope}
    \begin{axis}
    \addplot table[row sep=crcr] {0 0 \\ 1 1 \\};
    \end{axis}
    \end{scope}

    \begin{scope}[yshift=-7cm]
    \begin{axis}
    \addplot table[row sep=crcr] {0 1 \\ 1 0 \\};
    \end{axis}
    \end{scope}
    \end{tikzpicture}
\end{center}
\end{document}
3

The default is to located the lower left corner (anchor=south west) at the origin. One can apply shift directly to the axis to move it.

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{positioning}

\begin{document}
    \begin{tikzpicture}
    \begin{axis}[name=axis1]
    \addplot table[row sep=crcr] {0 0 \\ 1 1 \\};
    \end{axis}

    %\coordinate[below of=axis1.south] (test);% does not work
    \path (axis1.south) ++ (0,-1cm) coordinate (test);

    \begin{axis}[name=axis2, anchor=north, shift=(test)]
    \addplot table[row sep=crcr] {0 1 \\ 1 0 \\};
    \end{axis}

    \draw[red] (0,0) -- (axis1.south);
    \draw[green] (0,0) -- (axis2.north);

    \end{tikzpicture}
\end{document}

Just for fun, this shows how to use the local bounding box around the first axis to position the lower axis.

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{positioning}

\begin{document}
    \begin{tikzpicture}
    \begin{scope}[local bounding box=outer]
    \begin{axis}[name=axis1]
    \addplot table[row sep=crcr] {0 0 \\ 1 1 \\};
    \end{axis}
    \end{scope}

    \draw[red] (outer.south west) rectangle (outer.north east);
    \path (axis1.south |- outer.south) ++ (0,-.333em) coordinate (test);

    \begin{axis}[name=axis2, anchor=north, shift=(test)]
    \addplot table[row sep=crcr] {0 1 \\ 1 0 \\};
    \end{axis}

    \end{tikzpicture}
\end{document}
1

And here two other possibilities to position axis environments relative to each other.

  1. Using the at key and
  2. using the groupplots library

Both can be found in the PGFPlots manual. For details please have a look at the comments in the code.

% used PGFPlots v1.16
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
    % used for the second possibility
    \usepgfplotslibrary{groupplots}
    % common options
    \pgfplotsset{
        table/row sep=crcr,
    }
\begin{document}
    % first possibility
    \begin{tikzpicture}
        \begin{axis}[
            title={first possibility},
            xlabel=x label,
            % name the first `axis` environment
            name=axis1,
        ]
            \addplot table {0 0 \\ 1 1 \\};
        \end{axis}

        \begin{axis}[
            % position the second `axis` using `at` ...
            at={(axis1.below south west)},
            % ... and add a proper `anchor`
            anchor=north west,
            % optionally/additionally a `yshift` can be stated
            yshift=-5mm,
            ylabel=y label,
        ]
            \addplot table {0 1 \\ 1 0 \\};
        \end{axis}
    \end{tikzpicture}

    \hspace{1cm}

    % second possibility
    \begin{tikzpicture}
        % use the `groupplots` library and the `groupplot` environment
        \begin{groupplot}[
            group style={
                % state the alignment of the plots (`<horizontal> by <vertical>`)
                group size=1 by 2,
                % optionally state the vertical separation
                vertical sep=15mm,
            },
        ]
        \nextgroupplot[
            title={second possibility},
            xlabel=x label,
        ]
            \addplot table {0 0 \\ 1 1 \\};
        \nextgroupplot[
            ylabel=y label,
        ]
            \addplot table {0 1 \\ 1 0 \\};
        \end{groupplot}
    \end{tikzpicture}
\end{document}

image showing the result of above code

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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