[Tex/LaTex] “pgf Error: No shape named i-0 is known”, but only upon 2nd run

auxiliary-filesintersectionspgfplots

Update 2012-01-31:

  • This seems to be a version (and/or OS specific) problem. It breaks on my latest TeXLive2011 on a Mac, but I can get it to run on my PC version of MiKTeX 2.8, and @MarcvanDongen reports that it runs fine on a recently updated TeXLive on ubuntu.
  • Also works fine with TeXLive2010 on Mac.

The MWE below runs fine the first time, but upon the 2nd run only I get the error message normally the result of the case when there are no intersections:

./MyFigure.tex:49: Package pgf Error: No shape named i-0 is known.

I am using the usetikzlibrary{intersections} to compute the intersection and don't see why this should have anything to do with any auxiliary files, especially since the intersection is computed just fine upon the first run.

The MWE example below reproduces this error. It repeatedly includes MyFigure.tex which standalone yields:

enter image description here

Magical Fixes:

However, there are several seemingly unrelated things that seem to magically fix (or at least defer) this error, including:

  1. Decreasing the \NumberOfIterations below 35. Interestingly, in my actual usage I needed 42 instances to reproduce the problem, but somehow this number has shrunk when putting this into a MWE.

    @JosephWright suggested that this has to do with the number of pages changing between runs. Interestingly, the second page of the TOC starts when \NumberOfIterations is set to 34, and this case works fine.

  2. Eliminating the Watermark by commenting \def\AddWatermark{} (Tested up to 1000).

  3. Eliminate the phantom x-axis by commenting \def\AddPhantomXAxis{}.

    In my actual usage I draw a phantom (i.e., draw=none) x-axis to name the path in case the axis was not named previously. I realize in this case I do not need it (since my graph draws the x-axis and names it), but if I eliminate this phantom axis by commenting \def\AddPhantomXAxis{}, then this compiles just fine (Tested up to 1000).

  4. If I suppress the Table of Contents then things work just fine (Tested up to 1000). Comment out the line \def\AddTOC{} to test this.

  5. It seems that just redefining the \chapter macro to be identical to \section, then things also work. However, if \def\UseStandardChapter{} is commented, the problem occurs at 42 iterations (exactly where the second page of the TOC would start).

To simplify testing and hopefully help to get to the bottom of this problem I have provided several switches at the top:

\def\NumberOfIterations{35}% ok if this is 34 or less

% Commenting out any one of these results in the file being generated
\def\AddWatermark{}%       if commented works fine (tested to 1000)
\def\AddPhantomXAxis{}%    if commented works fine (tested to 1000)
\def\AddTOC{}%             if commented works fine (tested to 1000)
\def\UseStandardChapter{}% if commented, problem occurs at 42 (exactly where the second page of the TOC would start).

Notes:

  • I am using TeXLive2011 on a Mac. Have been able to reproduce the exact problem with an a version updated as of 2012-01-27.
  • Ensure that you remove the .aux files at beginning of first run, and ensure that you run it twice.
  • In my real usage I am clearing the name path globals at the end of each picture via the solution from Is there a way to clear paths previously defined with name path global in TikZ. It appears to not be necessary in this case, and is commented out in the MWE . However, just in case someone thinks that the problem is related to that I did not delete it.
  • The \ShowIntersectionWithXAxisPath is adapted from Intersections in PGFplots

Question:

Since this appears to be a bug, I am looking for a workaround that does not require me to eliminate the TOC, watermark, or phantom axis.

Code:

% First run is always fine (tested with \NumberOfIterations=500).
% But, 2nd run errors with: Package pgf Error: No shape named i-0 is known.
\def\NumberOfIterations{35}% ok if this is 34 or less

% Commenting out any one of these results in the file being generated
\def\AddWatermark{}%       if commented works fine (tested to 1000)
\def\AddPhantomXAxis{}%    if commented works fine (tested to 1000)
\def\AddTOC{}%             if commented works fine (tested to 1000)
\def\UseStandardChapter{}% if commented, problem occurs at 42 (exactly where the second page of the TOC would start).

\documentclass{book}

\ifdefined\UseStandardChapter
\else
    \renewcommand\chapter[1]{\section{#1}}
\fi

\usepackage{standalone}
\usepackage{pgfplots}
\usetikzlibrary{intersections}

\ifdefined\AddWatermark%% Problem on 2nd run if this is used
    \usepackage[all,center]{background}%
    \SetBgContents{\textsc{DRAFT}}%
    \SetBgOpacity{0.2}%
\fi

%% Does not appear to be needed to reproduce problem
%% https://tex.stackexchange.com/questions/21421/is-there-a-way-to-clear-paths-previously-defined-with-name-path-global-in-tikz
%
%\makeatletter%
%\tikzset{%
%  clear global paths/.style={%
%    execute at end picture=\clear@global@paths,%
%    name path global/.append code={%
%      \ifx\global@paths\pgfutil@empty%
%      \gdef\global@paths{##1}%
%      \else%
%      \xdef\global@paths{\global@paths,##1}%
%      \fi%
%    }%
%  },%
%  clear global paths now/.code={%
%    \expandafter\global\expandafter\let\csname tikz@intersect@path@name@#1\endcsname=\relax%
%  }%
%}%
%\let\global@paths=\pgfutil@empty%
%\def\clear@global@paths{%
%  \edef\@temp{\noexpand\pgfkeys{/tikz/clear global paths now/.list={\global@paths}}}%
%  \@temp%
%  \global\let\global@paths=\pgfutil@empty%
%  \global\let\tikz@intersect@namedpaths=\pgfutil@empty%
%}%
%\makeatother%

%%-----------------------------------------------------
\usepackage{filecontents}
\begin{filecontents}{MyFigure.tex}
\documentclass{article}
\usepackage{standalone}
\usepackage{pgfplots}
\usetikzlibrary{intersections}

\begin{document}

\ifdefined\AddPhantomXAxis
    \newcommand*{\DrawPhantomXAxis}{%% Problem on 2nd run if this is used
        % Draw a non-visible x-axis so that it can be 
        % used to determine intersections with x-axis
        \draw [mark=none, draw=none, name path=XAxisPath]%
            (current axis.left of origin) --%
            (current axis.right of origin);%
    }%
\else% Do absolutely nothing.
    \newcommand*{\DrawPhantomXAxis}{}%
\fi%


\newcommand*{\ShowIntersectionWithXAxisPath}[2]{
    \DrawPhantomXAxis{}% in case graphs did not have an x axis drawn
    \fill 
        [name intersections={of=#1 and XAxisPath, name=i, total=\t}] 
        [brown, opacity=1, every node/.style={black, opacity=1}] 
        \foreach \s in {1,...,\t}{(i-\s) circle (3pt)
            node [above left, red] {#2}};
}


\pgfmathdeclarefunction{GivenF}{1}{\pgfmathparse{exp(#1)-10^9}}
\begin{tikzpicture}

\begin{axis}[xmin=0.0, xmax=25, ymin=-1E9, ymax=1E9, xlabel=$x$, ylabel=$y$] 

% Draw x-axis
\addplot [name path global=XAxisPath, gray,thin] coordinates{(0.0,0.0) (25,0.0)};

% Graph Function
\addplot[domain=0.0:21.42, samples=50, ultra thick, blue, name path global=GraphCurve]
    ({x},{GivenF(x)})
    node [left,yshift=-3.5ex,blue] {$y = e^x -10^9$};

\ShowIntersectionWithXAxisPath{GraphCurve}{$x \approx 20.723$}
\end{axis} 
\end{tikzpicture}
\end{document}

\end{filecontents}
%-----------------------------------------------------

\begin{document}
\ifdefined\AddTOC
    \pagenumbering{roman}
    \tableofcontents
    \pagenumbering{arabic}
    \clearpage
\fi%

\chapter{First Chapter}
\foreach \x in {1,...,\NumberOfIterations}{
    \section{Section \x}
    \input{MyFigure.tex}
}
\end{document}

Best Answer

It is evident that the movement of document elements between runs cause the problem. This movement is related to the ToC only being typeset on the second (and subsequent) runs. As such, using Bruno's suggestion in set minimum number of pages for TOC, we use the a priori knowledge that Chapter 1 starts on (absolute) page 4, say, to insert only the necessary number of blank pages via:

\foreach \n in {\value{page},...,4} {\vbox{}\newpage}

Since \value{page} is relative to the location of \foreach, both the first and subsequent compiles will insert only the necessary number of pages in order retain a fixed start position.

The reference to "absolute" page numbering actually just refers to the page number within the most recent numbering scheme. However, since the numbering scheme is not changed until the first chapter in the MWE, the reference is absolute.

Here is the complete MWE that compiles without error:

\def\NumberOfIterations{35}% ok if this is 34 or less

% Commenting out any one of these results in the file being generated
\def\AddWatermark{}%       if commented works fine (tested to 1000)
\def\AddPhantomXAxis{}%    if commented works fine (tested to 1000)
\def\AddTOC{}%             if commented works fine (tested to 1000)
\def\UseStandardChapter{}% if commented, problem occurs at 42 (exactly where the second page of the TOC would start).

\documentclass{book}

\ifdefined\UseStandardChapter
\else
    \renewcommand\chapter[1]{\section{#1}}
\fi

\usepackage{standalone}
\usepackage{pgfplots}
\usetikzlibrary{intersections}

\ifdefined\AddWatermark%% Problem on 2nd run if this is used
    \usepackage[all,center]{background}%
    \SetBgContents{\textsc{DRAFT}}%
    \SetBgOpacity{0.2}%
\fi

%% Does not appear to be needed to reproduce problem
%% https://tex.stackexchange.com/questions/21421/is-there-a-way-to-clear-paths-previously-defined-with-name-path-global-in-tikz
%
%\makeatletter%
%\tikzset{%
%  clear global paths/.style={%
%    execute at end picture=\clear@global@paths,%
%    name path global/.append code={%
%      \ifx\global@paths\pgfutil@empty%
%      \gdef\global@paths{##1}%
%      \else%
%      \xdef\global@paths{\global@paths,##1}%
%      \fi%
%    }%
%  },%
%  clear global paths now/.code={%
%    \expandafter\global\expandafter\let\csname tikz@intersect@path@name@#1\endcsname=\relax%
%  }%
%}%
%\let\global@paths=\pgfutil@empty%
%\def\clear@global@paths{%
%  \edef\@temp{\noexpand\pgfkeys{/tikz/clear global paths now/.list={\global@paths}}}%
%  \@temp%
%  \global\let\global@paths=\pgfutil@empty%
%  \global\let\tikz@intersect@namedpaths=\pgfutil@empty%
%}%
%\makeatother%

%%-----------------------------------------------------
\usepackage{filecontents}
\begin{filecontents}{MyFigure.tex}
\documentclass{article}
\usepackage{standalone}
\usepackage{pgfplots}
\usetikzlibrary{intersections}

\begin{document}

\ifdefined\AddPhantomXAxis
    \newcommand*{\DrawPhantomXAxis}{%% Problem on 2nd run if this is used
        % Draw a non-visible x-axis so that it can be 
        % used to determine intersections with x-axis
        \draw [mark=none, draw=none, name path=XAxisPath]%
            (current axis.left of origin) --%
            (current axis.right of origin);%
    }%
\else% Do absolutely nothing.
    \newcommand*{\DrawPhantomXAxis}{}%
\fi%


\newcommand*{\ShowIntersectionWithXAxisPath}[2]{
    \DrawPhantomXAxis{}% in case graphs did not have an x axis drawn
    \fill 
        [name intersections={of=#1 and XAxisPath, name=i, total=\t}] 
        [brown, opacity=1, every node/.style={black, opacity=1}] 
        \foreach \s in {1,...,\t}{(i-\s) circle (3pt)
            node [above left, red] {#2}};
}


\pgfmathdeclarefunction{GivenF}{1}{\pgfmathparse{exp(#1)-10^9}}
\begin{tikzpicture}

\begin{axis}[xmin=0.0, xmax=25, ymin=-1E9, ymax=1E9, xlabel=$x$, ylabel=$y$] 

% Draw x-axis
\addplot [name path global=XAxisPath, gray,thin] coordinates{(0.0,0.0) (25,0.0)};

% Graph Function
\addplot[domain=0.0:21.42, samples=50, ultra thick, blue, name path global=GraphCurve]
    ({x},{GivenF(x)})
    node [left,yshift=-3.5ex,blue] {$y = e^x -10^9$};

\ShowIntersectionWithXAxisPath{GraphCurve}{$x \approx 20.723$}
\end{axis} 
\end{tikzpicture}
\end{document}

\end{filecontents}
%-----------------------------------------------------

\begin{document}
\ifdefined\AddTOC
    \pagenumbering{roman}
    \tableofcontents
%    \pagenumbering{arabic}
    \clearpage
\fi%

% Insert sufficient pages (only if necessary) to start
% first chapter on page 4. This leaves its position
% (and all subsequent ToC- and AUX-related content) fixed.
\foreach \n in {\value{page},...,4} {\typeout{test \thepage}\vbox{}\newpage}

\pagenumbering{arabic}% Only switch page numbering here, since this also sets page counter to 1
\chapter{First Chapter}
\foreach \x in {1,...,\NumberOfIterations}{
    \section{Section \x}
    \input{MyFigure.tex}
}
\end{document}
Related Question