Abstract
I use current axis for drawing my axes and add labels to them but, if tikzmarks are used on a tikzpicture, current axis doesn't behave well in the next ones.
My main goal is to find out why this is happening.
Note:(Sorry for the huge question) Please don't be scared by its size, you can skip the Research and the Approaches (and their disadvantages) sections if you know about this problem already.
MWE and description
I am using tikzmark to add some information in a pseudocode of algorithm2e. In addition, I use Andrew's answer to reuse tikzmarks' names, although I don't believe the issue lies in that fact.
Then, completely apart from that, I create a tikzpicture and manually draw the axes and label them using current axis (I find this way more friendly) so that I don't have to think about it.
However the tikzmarks are messing up the reference positions of the current axis of the next tikzpictures.
Thus, am I doing something wrong? How can I correct that?
\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}
Notes
Here there are some notes that I think are important:
- I don't want to externalize the first
tikzpicture(related to the pseudocode). memoirclass is mandatory, since I must use a template based on that one (university requirements).algorithm2eis mandatory, since my full document has a complex personalized pseudocode created with features from this package.mode=list and makeoption is mandatory, since my full document has\ref,\labeland\citeinsidetikzpictures.only namedoption is mandatory, since all my workflow depends on it to eliminate externalization of punctual images.- As I extensively use
pgfandtikz, changing\pgfplotsset{compat=1.17}or removing it is far more dangerous to the health of my entire document, so don't want to take this risk. - It would be good (but not mandatory) if I could maintain
tikzmark, since everything have already been done and redo it will consume more time than manually draw axes (see approaches bellow). - I compile this MWE on
Tex Live, usingCygWinon Windows (sorry to disappoint you) and with the following commands:
pdflatex -interaction=batchmode main
make -j 4 -f main.makefile
pdflatex -interaction=batchmode -synctex=1 main
Research
The most important discovery was made in pgfplots manual (Section 4.19.5 - Miscellaneous for Alignment, p.381, v.1.17), which states:
Remark: If you use current axis inside of axis descriptions, the “current axis” is not yet finished. That means you can’t use any outer anchor inside of axis descriptions.
It is also possible to use current axis in any drawing or plotting commands inside of an axis (but no outer anchor as these are not defined when drawing commands are processed). This usage is similar to the axis description cs.
I must confess that really don't know if it has to do with my problem (maybe it helps you), because, for me, "axis descriptions" are the one that would be inside the square brackets [ ].
Also I've found some other questions (not so related, though), but they haven't helped me so much:
- Positioning with
current axisdepending on limits? - Apply shift to (current axis.left of origin)
- Tikz External vs. Overlay
- Are tikzmark and tikzexternalize incompatible? [targeting sub-nodes]
- Issues with tikzmark
Approaches (and their disadvantages)
Here I want to show you some attempts to find the cause and some workarounds (which are not perfect, since I don't know the source of the problem)
1) To make use of tikzmark
You may think that the problem arises when I don't make use of tikzmarks, but that's not the case: if I give them a use (here I relied on Andrew's answer to reuse tikzmarks' names) the problem persists:
Added in preamble:
\newcounter{tmkcount}
\tikzset{
use tikzmark/.style={
remember picture,
overlay,
execute at end picture={
\stepcounter{tmkcount}
},
},
tikzmark suffix={-\thetmkcount}
}
Added after \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) Completely removing tikzmark
If I remove everything related to tikzmark, the problem disappears.
Removed from preamble:
\usetikzlibrary{tikzmark}
Removed from code (first line of pseudocode):
\tikzmark{startG}some code here with tikzmark: $x=y$\tikzmark{endG}\\
Drawbacks: Without tikzmark I can't precisely draw the extra information in my pseudocode.
3) Replace tikzmark by pgfmark
From page 5 of tikzmark package, I tried to replace tikzmark by pgfmark.
Changed in code (first line of pseudocode):
\pgfmark{startG}some code here with tikzmark: $x=y$\pgfmark{endG}\\
It worked at first glance, but when I tried to make use of the pgfmark (with the same piece of code that I provided in first attempt) things went wrong:
Drawbacks: I'm not used to pgfmark and don't know how to use it properly, also I would been changing a problem for another.
4) Get rid of current axis
As far as I can see, this is the "less bad" solution. If I eliminate current axis at the second tikzpicture and draw the axes manually, I can achieve my desired output.
Replace lines:
\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$};
By:
\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$};
Drawbacks: I'll be forced to manually think about the coordinates of the axes. I also want to understand the cause of this problem, because since I've faced it I don't feel confident enough to keep using referenced positioning as it's showing a bad behavior.
5) Not to externalize the second image
Well, that also solves the problem, but I actually have many images and not to use externalization will greatly increase the compilation time.
Removed from code (above the second \begin{tikzpicture}):
\tikzset{external/remake next}
\tikzsetnextfilename{tikz_fig}
Drawbacks: It slows down compilation.
6) Externalizing everything
It makes things worse than they already are.
Added in code (bellow \end{algorithm}):
\tikzsetnextfilename{tikz_fig_aux}









tikzmarks. On my MWE it only caused a downward shift, but when I ran a test on the entire document, everytikzmarkwere messed up. I think it might be considered a solution when we are starting the document (so I'll mark this answer as the accepted one for now), however, it isn't my case though :( , since redoingtikzmarks will consume more time than replacing thecurrent axis. – Leone Mar 13 '21 at 04:00tikzmarks, the problem seems to be just some horizontal or vertical shifts (with distinct distances). – Leone Mar 13 '21 at 04:22