10

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}
14
  • 1
    Did you also notice that running it 3 times removes any errors?
    – percusse
    Commented Jan 24, 2012 at 1:15
  • @percusse: Interesting I did not notice that. Perhaps the .aux files are invalidated since the prior run did not complete so third run is same as 1st run? Just a guess though, don't know much about those files yet. Commented Jan 24, 2012 at 1:24
  • This works fine for me. I've run it three times.
    – user10274
    Commented Jan 27, 2012 at 18:40
  • @MarcvanDongen: I am using TeXLive2011 on a Mac. What version are you using? Do you perhaps have a newer version of the intersections library? Commented Jan 27, 2012 at 20:28
  • @PeterGrill I'm using TeX Live (recently updated) on ubuntu. You code ran without causing runtime errors for me.
    – user10274
    Commented Jan 28, 2012 at 0:19

2 Answers 2

3
+500

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}
11

The problem is due to how pgf tracks items between runs using the .aux file, and how this interacts with your particular situation. On the first run, there is no .aux file and so no issues.

During this first run, pgf writes a number of lines of the form

\pgfsyspdfmark {pgfid<id>}{<x>}{<y>}

to the .aux file. These are used to track items with an absolute position (the x and y values are generated by the engine's position-tracking system). In a 'normal' case, the id values will not change between runs, and so when the second run starts everything will match up. The number and location of the id values here suggests that there is one for each watermark, which don't even get printed in the first run as they have no mark information at that stage.

Normally, a second run uses the mark information to place absolute items: the watermarks in this case. What happens in your case is a little complex. With 35 or more sections, the page layout and so forth causes an additional page to be added as part of the TOC. This then means that the id values for the pgf graphics (watermarks, plots and axes) change. That messes up the id for every watermark after the new page.

What's not quite clear to me is how this links to the phantom axes. I suspect that this must be a bug somewhere in pgf, as this seems also to link to the 'choice' of i-0 as the name of the invalid mark. My suspicion is that this is linked to how the id values are managed, but that would be easier for the developers to work out!

You'll also notice that if you keep going past the errors in the second run, any later runs are fine. That is because the marks are all then correct, and so pgf can look up the appropriate information.

7
  • Did some more testing regarding "any later runs are fine". Run 3 and 4 produce identical temporary files, but then run 5 reproduces the problem as was the case in run 2. Commented Jan 26, 2012 at 21:14
  • Also tried changing the node names from i- to MyIntersectionsPeterGrill- and still get error, so not due to the choice of node name. Commented Jan 26, 2012 at 21:18
  • I only tried 4 runs: the .aux seemed to be settled at that stage. As I said, I'm not actually sure where i-0 comes from: if you deliberately mess with the .aux file, you also get i-1 here in some cases.
    – Joseph Wright
    Commented Jan 26, 2012 at 21:23
  • @PeterGrill If you replace both occurrences of i (as the name) with something else in your demo, then you get <something-else>-0 in the error. So that is where pgf picks up the incorrect name from, but I'm not sure why.
    – Joseph Wright
    Commented Jan 27, 2012 at 14:18
  • 1
    @PeterGrill Count the pages! With 34 iterations, you have two pages before the plots start both on the first run and on later runs. With 35 interactions, you have two pages before the plots on the first run, but three on the second run.
    – Joseph Wright
    Commented Jan 28, 2012 at 15:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .