pgf-tikz / pgfplots

pgfplots - A TeX package to draw normal and/or logarithmic plots directly in TeX in two and three dimensions with a user-friendly interface and pgfplotstable - a TeX package to round and format numerical tables. Examples in manuals and/or on web site.

Home Page:http://pgfplots.sourceforge.net/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`scope` nested inside `axis` does not have access to shapes constructed in `axis` during its own construction

ORippler opened this issue · comments

Brief outline of the bug

When constructing a scope inside an axis environment, variables/shapes defined inside the axis environment are not accessible when constructing the scope, but can surprisingly be accessed again after entering the scope.
This becomes problematic, as current axis becomes inaccessible for scope construction.

Minimal working example (MWE)

\documentclass{article}
\usepackage{tikz, pgfplots}
\pgfplotsset{compat=newest}
  % Any preamble code goes here

\begin{document}

\begin{tikzpicture}
    \coordinate(foofoo);
    \begin{axis}
        \node[draw] (foo) at (current axis.origin) {foo};
        \coordinate(bar) at (foo.east);              %   <----- referencing shapes constructed inside `axis` works inside the `axis` as expected
        %\begin{scope}[rotate around={-45:(foofoo)}] %   <----- shapes constructed outside `axis` can be referenced for `scope` construction
        \begin{scope}[rotate around={-45:(foo)}]     %   <----- shapes constructed inside `axis` CAN NOT be referenced for `scope` construction. This includes `current axis`
            \addplot [draw=green, domain=-5:5] {x};
            \coordinate(barbar) at (foo.east);       %   <----- shapes constructed inside `axis` can again be referenced inside the `scope`
        \end{scope}
        \addplot [draw=red, domain=-5:5] {x};
    \end{axis}
\end{tikzpicture}

\end{document}

Tested with package versions:

Package: tikz 2021/05/15 v3.1.9a (3.1.9a)
Package: pgfplots 2021/05/15 v1.18.1 Data Visualization (1.18.1)

pgfplots is not part of PGF. I moved your issue to the correct repository.

I think what you are seeing is by design, because axes are constructed asynchronously. Obviously the axis lines and ticks can only be placed once the dimensions of all plots are known, so placement of objects is delayed until \end{axis} which is is why you cannot refer to objects constructed inside the axis before \end{axis}.

Thanks for moving the issue to the correct repo !

which is is why you cannot refer to objects constructed inside the axis before \end{axis}.

I am confused by this. I can refer to shapes constructed inside axis after the scope has been entered: constructing the coordinate barbar, which refers to foo.east, which has been constructed inside axis, passes. The thing that confuses me is that I can access them after I have entered the scope, but not during the construction of the scope. This lead me to believe this might be a bug rather than intended behavior.

The problem is that scope has not been adapted to use “delayed” coordinates the same way that \path (and therefore \node and \coordinate) has been. There is probably also no automatic translation into axis cs: coordinates for scope but I'm not sure whether this is worth fixing at all because of the unreasonable complexity of context-dependent overriding of PGF keys.

EDIT: You can learn more by searching the codebase for the undocumented \axispath command.

The thing that confuses me is that I can access them after I have entered the scope, but not during the construction of the scope.

That would be true if pgfplots was executing the statements immediately. But instead it has a collect phase before the drawing phase to figure out the axis properties etc. and when everything is collected and prepared then it places the objects. Hence while it is collecting foo is not established yet in the namespace. But during the execution they are all executed consecutively and that's why it is available inside the scope.

Another example for this is the PGF's foreach. Often the the loop is exhausted at the collection phase before any drawing is done hence the commands pgfplotsinvokeforeach and pgfplotsforeachungrouped. See an example here https://tex.stackexchange.com/q/69445