抽象的
我用来current axis
绘制轴并为其添加标签,但是,如果tikzmark
在 a 上使用 s tikzpicture
,current axis
则在接下来的轴上表现不佳。
我的主要目标是找出发生这种情况的原因。
笔记:(抱歉,这个问题太大了)请不要害怕它的大小,你可以跳过研究和方法(及其缺点)如果您已经了解此问题,请查阅相关部分。
MWE 和描述
我使用tikzmark
在 的伪代码中添加一些信息algorithm2e
。此外,我使用安德鲁的回答重复使用tikzmark
s 的名字,尽管我不认为问题在于此。
然后,除此之外,我创建一个tikzpicture
并手动绘制轴并使用它们进行标记current axis
(我发现这种方式更友好),这样我就不必考虑它了。
然而,tikzmark
s 却扰乱了current axis
下一个tikzpicture
s 的参考位置。
那么,我做错了什么吗?我该如何纠正?
\documentclass{memoir}
\usepackage{algorithm2e}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.17}
\usetikzlibrary{tikzmark}
\usetikzlibrary{external}
\tikzexternalize[
mode=list and make,
only named=true,
]
\begin{document}
\begin{algorithm}
\tikzmark{startG}some code here with tikzmark: $x=y$\tikzmark{endG}\\
some code here without tikzmark: $x=y$
\end{algorithm}
\tikzset{external/remake next} % Just to force remake for troubleshooting
\tikzsetnextfilename{tikz_fig}
\begin{tikzpicture}
\begin{axis}[
x=1cm, y=7cm,
xmin=-1, xmax=11,
ymin=-0.1, ymax=1.1,
]
\draw[->] (current axis.below origin) -- (current axis.above origin);
\draw[->] (current axis.left of origin) -- (current axis.right of origin);
\begin{scriptsize}
\draw (current axis.above origin) node[below left] {$a(t)$};
\draw (current axis.right of origin) node[below left] {$t$};
\end{scriptsize}
\end{axis}
\end{tikzpicture}
\end{document}
笔记
以下是我认为重要的一些注释:
- 我不想外部化第一个
tikzpicture
(与伪代码相关)。 memoir
课程是必修的,因为我必须使用基于该课程的模板(大学要求)。algorithm2e
是强制性的,因为我的完整文档具有使用此包的功能创建的复杂的个性化伪代码。mode=list and make
选项是强制性的,因为我的完整文档有\ref
,\label
并且在 s\cite
里面tikzpicture
。only named
该选项是强制性的,因为我的所有工作流程都依赖于它来消除准时图像的外部化。- 由于我广泛使用
pgf
和tikz
,更改\pgfplotsset{compat=1.17}
或删除它对我的整个文档的健康来说更为危险,所以不想冒这个风险。 - 这将是很好的 (但不是强制性的)如果我能坚持下去
tikzmark
,因为所有事情都已经完成了,重做会比手动绘制轴花费更多的时间(参见以下方法)。 Tex Live
我在 Windows 上使用编译了这个 MWECygWin
(很抱歉让您失望了)并使用以下命令:
pdflatex -interaction=batchmode main
make -j 4 -f main.makefile
pdflatex -interaction=batchmode -synctex=1 main
研究
最重要的发现发生在pgfplots
手动的(第 4.19.5 节 - 对齐杂项,第 381 页,v.1.17),其中指出:
备注:如果您在轴描述中使用当前轴,则“当前轴”尚未完成。这意味着您不能在轴描述中使用任何外部锚点。
还可以在轴内的任何绘图或绘图命令中使用当前轴(但没有外部锚点,因为在处理绘图命令时未定义这些锚点)。此用法类似于轴描述 cs。
我必须承认,我真的不知道这是否与我的问题有关(也许它对你有帮助),因为对我来说,“轴描述”就是方括号内的描述[ ]
。
此外,我还发现了一些其他问题(虽然不太相关),但它们对我没有太大帮助:
- 定位
current axis
取决于限制吗? - 将移位应用于(当前轴.原点左侧)
- Tikz 外部与覆盖
- tikzmark 和 tikzexternalize 不兼容吗?[针对子节点]
- tikzmark 的问题
方法(及其缺点)
在这里我想向您展示一些寻找原因的尝试和一些解决方法(这些尝试并不完美,因为我不知道问题的根源)
1)利用tikzmark
你可能会认为当我不使用tikzmark
s 时就会出现问题,但事实并非如此:如果我给他们一个用途(这里我依靠安德鲁的回答重复使用tikzmark
s 的名称)问题仍然存在:
在序言中添加:
\newcounter{tmkcount}
\tikzset{
use tikzmark/.style={
remember picture,
overlay,
execute at end picture={
\stepcounter{tmkcount}
},
},
tikzmark suffix={-\thetmkcount}
}
添加于\end{algorithm}
:
\begin{tikzpicture}[use tikzmark]
\newdimen\deslocamento
\pgfmathsetlength{\deslocamento}{200 pt}
\coordinate (Go) at (pic cs:startG);
\coordinate (Gf) at (pic cs:endG);
\draw[decoration={brace,raise=\deslocamento},decorate]
([yshift=12pt] Go)
-- node[xshift=\deslocamento+5pt,right,align=left]{some text}
([yshift=-5pt] Go |- Gf);
\end{tikzpicture}
2)彻底清除tikzmark
如果我删除与之相关的所有内容tikzmark
,问题就会消失。
从序言中删除:
\usetikzlibrary{tikzmark}
从代码中删除(伪代码的第一行):
\tikzmark{startG}some code here with tikzmark: $x=y$\tikzmark{endG}\\
缺点:没有tikzmark
它我就无法在我的伪代码中精确地绘制额外的信息。
3)替换tikzmark
为pgfmark
从第 5 页包中tikzmark
,我尝试用tikzmark
替换pgfmark
。
代码中发生了改变(伪代码的第一行):
\pgfmark{startG}some code here with tikzmark: $x=y$\pgfmark{endG}\\
乍一看它是有效的,但是当我尝试使用pgfmark
(使用我在第一次尝试中提供的相同代码)时,事情就出错了:
缺点:我还不习惯pgfmark
也不知道如何正确使用它,而且我还会把一个问题变成另一个问题。
4)摆脱current axis
据我所知,这是“不太糟糕”的解决方案。如果我current axis
在第二个位置消除tikzpicture
并手动绘制轴,我就可以实现我想要的输出。
替换行:
\draw[->] (current axis.below origin) -- (current axis.above origin);
\draw[->] (current axis.left of origin) -- (current axis.right of origin);
\draw (current axis.above origin) node[below left] {$a(t)$};
\draw (current axis.right of origin) node[below left] {$t$};
经过:
\draw[->] (0,-0.1) -- (0,1.1);
\draw[->] (-1,0) -- (11,0);
\draw (0,1.1) node[below left] {$a(t)$};
\draw (11,0) node[below left] {$t$};
缺点:我将被迫手动思考轴的坐标。我还想了解这个问题的原因,因为自从我遇到这个问题以来,我没有足够的信心继续使用参考定位,因为它表现出了不良行为。
5)不要外化第二幅图像
嗯,这也解决了问题,但是我实际上有很多图像,如果不使用外部化将大大增加编译时间。
从代码中删除(第二个以上\begin{tikzpicture}
):
\tikzset{external/remake next}
\tikzsetnextfilename{tikz_fig}
缺点:它会减慢编译速度。
6)外化一切
它使事情变得比本来的更糟糕。
添加代码(如下\end{algorithm}
):
\tikzsetnextfilename{tikz_fig_aux}
答案1
我可以重现该问题,而无需在 pgfplots 环境之前对 tikz 图片tikzmark
使用remember picture
键。我不清楚发生了什么,但这似乎是由于remember picture
写入辅助文件并在 pgfplots 图片外部化时读回并弄乱了 pgfplots 环境中的某些内容。
一种可能的解决方法是使用\tikzifexternalizing
在处理主文件和生成外部图像之间切换行为。通过实验,我认为放置它的正确位置实际上是在文件中aux
,这意味着我们需要修改将其写出的例程。这可能会破坏其他东西,不过,我还没有在本文档之外测试过它。
\documentclass{memoir}
%\url{https://tex.stackexchange.com/q/586927/86}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.17}
\usetikzlibrary{external}
\tikzexternalize[
mode=list and make,
only named=true,
]
\makeatletter
\def\pgfsys@markposition#1{%
\savepos% lualatex
% \pdfsavepos% pdflatex & xelatex
\edef\pgf@temp{#1}%
\expandafter\pgfutil@writetoaux\expandafter{%
\expandafter\noexpand\expandafter\tikzifexternalizing\expandafter{\expandafter}\expandafter{\expandafter\noexpand\expandafter\pgfsyspdfmark\expandafter{\pgf@temp}{\the\lastxpos}{\the\lastypos}}}%
% for pdftex and xelatex use \pdflastxpos and \pdflastypos
}
\makeatother
\begin{document}
\tikz[remember picture] \draw (0,0) -- (1,0);
\tikzset{external/remake next} % Just to force remake for troubleshooting
\tikzsetnextfilename{tikz_fig}
\begin{tikzpicture}
\begin{axis}[
x=1cm, y=7cm,
xmin=-1, xmax=11,
ymin=-0.1, ymax=1.1,
]
\draw[->] (current axis.below origin) -- (current axis.above origin);
\draw[->] (current axis.left of origin) -- (current axis.right of origin);
\begin{scriptsize}
\draw (current axis.above origin) node[below left] {$a(t)$};
\draw (current axis.right of origin) node[below left] {$t$};
\end{scriptsize}
\end{axis}
\end{tikzpicture}
\end{document}
(注意:我使用lualatex
,对于pdflatex
,xelatex
您需要对的定义做一些调整,\pgfsys@markposition
如图所示。)