在解决方案中PGFplot 中的交叉点有人指出,每个\addplot
命令都在其自己的范围内绘制,并且 usingname path
在该命令之外不会存在\addplot
。解决方案是使用name path global
,以便\addplot
生成该路径的特定路径之外的人可以知道路径名称。这很好用——但是,在大型文档中,可能会再次使用相同的名称。
想知道是否有办法清除通过命名的路径name path global
。即使我需要在当前环境之外执行此操作,\tikzpicture
那也没问题,因为我只需\tikzpicture
在每张图片使用后添加一个空的执行此清理即可。这将是更好的选择,因为这样我就不必担心名称冲突了。
我没有在文档中看到有关此内容的任何内容,因此,如果目前不可能的话,这可能是未来版本的一个值得考虑的好功能。
**** 更新(使用 Andrew 提供的 sol'n)****
尝试使用 sol'n,但它似乎只清除了第一条路径。如果第二张图中的路径名称发生更改(并显示 2 个交叉点),则以下代码可以正常工作,但显示 4 个交叉点,如下所示
\documentclass{standalone}
\usepackage{pgfplots}
\usetikzlibrary{intersections}
\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
}
\makeatother
%--------------------------------------------------
\begin{document}
\newcommand*{\ShowIntersection}[2]{
\fill
[name intersections={of=#1 and #2, name=i, total=\t}]
[red, opacity=1, every node/.style={above left, black, opacity=1}]
\foreach \s in {1,...,\t}{(i-\s) circle (2pt)
node [above left] {\s}};
}
\begin{tikzpicture}[clear global paths]
\draw[name path global=GraphCurve, mark=none, domain=-2.5:2.5, thick] plot ({\x},{\x*\x});%
\draw [red, thick, name path global=HorizontalLine] (-2.5,3) -- (2.5,3);%
\ShowIntersection{GraphCurve}{HorizontalLine}
\end{tikzpicture}
\begin{tikzpicture}[clear global paths]
\begin{axis}
\addplot[name path global=GraphCurve, mark=none, domain=-2.5:2.5, thick] ({x},{x*x});%
\addplot [red, thick, name path global=HorizontalLine] coordinates{(-2.5,4) (2.5,4)};%
\ShowIntersection{GraphCurve}{HorizontalLine}
\end{axis}
\end{tikzpicture}
\end{document}
答案1
路径存储在宏中,\tikz@intersect@path@name@<name of path>
因此要清除路径,您需要将该宏清空。最粗暴但最简单的方法是将\let
其简单地置于环境\relax
之后tikzpicture
。更花哨的方法是在图片末尾放置一个新的钩子,以清空该图片中定义的全局路径。为此,我们需要通过在命名键中添加一些代码来存储要清空的路径名称列表,然后我们依次通过该列表设置每个路径\relax
。因此:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{intersections}
\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
\begin{document}
\begin{tikzpicture}[clear global paths]
\draw[name path global=path] (0,0) -- (1,0);
\draw[name path global=another path] (0,0) -- (1,0);
\makeatletter
\show\global@paths
\makeatother
\end{tikzpicture}
\makeatletter
\show\tikz@intersect@path@name@path
\show\global@paths
\makeatother
\end{document}
在 中tikzpicture
,\global@paths
是已全局定义的路径的逗号分隔列表。在图片的末尾,我们处理这个列表,清空每个路径(如 的输出所示\show
),然后最终清空我们的列表以准备下一次调用。
更新:事实证明 TikZ 尝试真的很难记住全局命名的路径,以至于有一个宏可以重建命名路径。我很难看到它在哪里定义,因为无论我把\show\tikz@intersect@namedpaths
里面那么我tikzpicture
什么也得不到,但如果我把它直接放在后面,那么我就会得到重建所需的代码姓氏路径(和仅有的最后命名的那个)。因此,在结束的代码中的某个地方tikzpicture
,该宏被设置。我在上面添加了代码来将其清空,这似乎解决了问题。因为它只记住最后的全局命名路径,我猜这不应该发生,所以我不会因为将其清空而感到内疚。但请注意,我不知道它是做什么用的,也不知道它在哪里设置,所以其他东西可能会因此而中断(尽管我对此表示怀疑)。