“pgf 错误:没有已知的名为 i-0 的形状”,但仅在第二次运行时出现

“pgf 错误:没有已知的名为 i-0 的形状”,但仅在第二次运行时出现

更新2012-01-31:

  • 这似乎是版本(和/或操作系统特定)问题。它在我最新的 Mac 版 TeXLive2011 上崩溃了,但我可以在 PC 版 MiKTeX 2.8 上运行它,@MarcvanDongen 报告说它在 ubuntu 上最近更新的 TeXLive 上运行良好。
  • 在 Mac 上也可以很好地与 TeXLive2010 配合使用。

下面的 MWE 第一次运行良好,但只有在第二次运行时我才会收到错误消息,这通常是没有交集的情况的结果:

./MyFigure.tex:49:包 pgf 错误:没有已知名为 i-0 的形状。

我正在使用来usetikzlibrary{intersections}计算交点,但不明白为什么这与任何辅助文件有什么关系,特别是因为交点在第一次运行时就计算得很好。

下面的 MWE 示例重现了此错误。它反复包含MyFigure.tex哪些独立产品:

在此处输入图片描述

魔法修复:

然而,有几件看似不相关的事情似乎神奇地修复(或至少推迟)此错误,包括:

  1. 减少\NumberOfIterations以下35。有趣的是,在我的实际使用中,我需要 42 个实例来重现该问题,但当将其放入 MWE 时,这个数字不知何故缩小了。

    @JosephWright 认为这与运行之间更改的页数有关。有趣的是,当\NumberOfIterations设置为时,目录的第二页开始34,这种情况运行正常。

  2. 通过评论消除水印\def\AddWatermark{}(已测试最多 1000 条)。

  3. 通过注释消除幻影 x 轴\def\AddPhantomXAxis{}

    在实际使用中,我绘制了一个幻影(即draw=none)x 轴来命名路径,以防之前没有命名轴。我意识到在这种情况下我不需要它(因为我的图表绘制了 x 轴并命名了它),但如果我通过注释来消除这个幻影轴\def\AddPhantomXAxis{},那么就可以很好地编译(测试了 1000 次)。

  4. 如果我隐藏目录,那么一切就都正常了(测试了 1000 个)。注释掉该行\def\AddTOC{}以进行测试。

  5. 似乎只需将\chapter宏重新定义为与 相同\section,那么一切就都可以了。但是,如果\def\UseStandardChapter{}注释了 ,问题就会出现在第 42 次迭代处(恰好是目录第二页的开始位置)。

为了简化测试并希望有助于彻底解决这个问题,我在顶部提供了几个开关:

\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).

笔记:

  • 我在 Mac 上使用 TeXLive2011。使用 2012-01-27 更新的版本可以重现完全相同的问题。
  • 确保在第一次运行开始时删除 .aux 文件,并确保运行两次。
  • 在我的实际使用中,我通过以下解决方案清除name path globals每张图片末尾的有没有办法清除 TikZ 中先前用名称 path global 定义的路径。在这种情况下,它似乎没有必要,并且在 MWE 中被注释掉了。但是,以防万一有人认为问题与此有关,我没有删除它。
  • 改编\ShowIntersectionWithXAxisPathPGFplot 中的交叉点

问题:

由于这似乎是一个错误,我正在寻找一种不需要消除目录、水印或幻影轴的解决方法。

代码:

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

答案1

显然,文档元素在运行之间的移动导致了这个问题。这种移动与目录仅在第二次(及后续)运行中排版有关。因此,使用 Bruno 的建议设置目录的最小页数,我们使用先验知道第 1 章从(绝对)第 4 页开始,例如,通过以下方式仅插入必要数量的空白页:

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

由于是\value{page}相对于的的位置\foreach,因此第一次和后续编译都仅插入必要数量的页面以保留固定的起始位置。

提到“绝对”页码实际上只是指最新编号方案中的页码。但是,由于编号方案直到 MWE 的第一章才发生变化,因此引用是绝对的。

这是编译时没有错误的完整 MWE:

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

答案2

问题在于如何pgf使用文件在运行之间跟踪项目.aux,以及这与你的特定情况如何交互。第一次运行时没有.aux文件,所以没有问题。

在第一次运行期间,pgf写入多行格式

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

.aux文件。这些用于跟踪具有绝对位置的项目(X值由发动机的位置跟踪系统生成)。在“正常”情况下,ID值在运行之间不会改变,因此当第二次运行开始时,所有内容都会匹配。ID这里的值表明每个水印都有一个,由于在那个阶段它们没有标记信息,所以在第一次运行中甚至不会打印。

通常,第二次运行会使用标记信息来放置绝对项目:本例中为水印。您的情况有点复杂。如果有 35 个或更多部分,页面布局等会导致将附加页面添加为目录的一部分。这意味着ID图形(水印、图表和轴)的值pgf会发生变化。这会弄乱ID新页面后的每个水印。

我不太清楚的是这与幻影轴有何关联。我怀疑这一定是 中的某个错误pgf,因为这似乎也与 的“选择”i-0作为无效标记的名称有关。我怀疑这与ID值是可管理的,但这对于开发人员来说会更容易解决!

您还会注意到,如果您继续检查第二次运行中的错误,则以后的任何运行都会正常。这是因为标记都是正确的,因此pgf可以查找相应的信息。

相关内容