2

Consider the following MWE. The code of \mypic positions a line between two nodes. When I try to use \mypic with the tikzmark library, the positioning of the line is incorrect. Why is this happening, and how can I fix it?

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{tikzmark,positioning,calc}
\NewDocumentCommand{\markpic}{m}{\tikz[remember picture]{\node[overlay,above=of pic cs:#1]{\mypic};}}
\NewDocumentCommand{\mypic}{}{
\begin{tikzpicture}
\node[circle=3pt,fill] at (0,0) {};
\draw[] (-.5,-.5) -- (.5,-.5);
\node[circle=3pt,fill] at (0,-1) {};
\end{tikzpicture}
}
\begin{document}

The diagram \tikzmark{C} above is incorrect. \markpic{C} \bigskip

The diagram below is correct. \bigskip

\mypic

\end{document}

output of code

Alan Munn
  • 218,180

1 Answers1

3

One should not nest tikzpictures. By putting a tikzpicture in a node of another tikzpicture you are doing just that. If you store the inner tikzpicture in a box, you are safe. Alternatively you could use a pic, but the box is faster.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{tikzmark,positioning,calc}
\NewDocumentCommand{\markpic}{m}{\tikz[remember picture]{\node[overlay,above=of pic cs:#1]{\mypic};}}
\newsavebox\mypicbox
\sbox\mypicbox{\begin{tikzpicture}
    \node[circle=3pt,fill] at (0,0) {};
    \draw[] (-.5,-.5) -- (.5,-.5);
    \node[circle=3pt,fill] at (0,-1) {};
    \end{tikzpicture}}
\NewDocumentCommand{\mypic}{}{\usebox\mypicbox}
\begin{document}

The diagram \tikzmark{C} above is incorrect. \markpic{C} \bigskip

The diagram below is correct. \bigskip

\mypic

\end{document}

If you really need to nest tikzpictures, you need to make precautions that the inner tikzpicture does not use certain keys of the ambient one. In this case, the problem is above, which sets the anchor to south. Therefore the circles appear to be displaced. Alternatively, you could avoid using nodes for the circles, and just fill some circles. (In nodes, the circle key is a shortcut for shape=circle, and it does not take arguments, so circle=3pt is the same as circle in this context. You can set the radius via the inner sep key.)

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{tikzmark,positioning,calc}
\NewDocumentCommand{\markpicA}{m}{\tikz[remember picture]{\node[overlay,above=of pic cs:#1]{\mypicA};}}
\NewDocumentCommand{\markpicB}{m}{\tikz[remember picture]{\node[overlay,above=of pic cs:#1]{\mypicB};}}
\NewDocumentCommand{\mypicA}{}{\begin{tikzpicture}[nodes={anchor=center}]
\node[circle,fill] at (0,0) {};% circle does not options, so "3pt" can be dropped
\draw[] (-.5,-.5) -- (.5,-.5);
\node[circle,fill] at (0,-1) {};
\end{tikzpicture}}

\NewDocumentCommand{\mypicB}{}{\begin{tikzpicture} \fill[radius=3pt] (0,0) circle; \draw[] (-.5,-.5) -- (.5,-.5); \fill[radius=3pt] (0,-1) circle; \end{tikzpicture}}

\begin{document}

The diagram \tikzmark{C} above is now correct. \markpicA{C} \bigskip

The diagram below is correct. \bigskip

\mypicA

\vspace{4em}

The diagram \tikzmark{D} above is now correct. \markpicB{D} \bigskip

The diagram below is correct. \bigskip

\mypicB

\end{document}

enter image description here

  • Thanks, I thought that might be the problem. This is very simplified code from a package, so ideally I'd like a way to "insulate" my command and allow its use like this without a savebox. – Alan Munn Feb 21 '23 at 04:17
  • @AlanMunn This can also help? https://tex.stackexchange.com/questions/46598/problem-with-overlay-when-a-tikzpicture-is-inside-another-tikzpicture – quark67 Feb 21 '23 at 04:19
  • @AlanMunn You can avoid the misplacement of the circle nodes by setting their anchor to be center. The problem is that in the ambient tikzpicture you use the above key, which sets the anchor to south, so you need to undo this. I added a code for this scenario. There can be other "offending" keys which you may have to undo in a similar fashion in variations of this scenario. –  Feb 21 '23 at 04:34
  • Thanks! That solves the problem nicely. In general the code will not be embedded in another tikzpicture except in this particular tikzmark case, so I'll take my chances on embedding by adding the nodes={anchor=center} to my picture style. The circle=3pt is not actually used in my real code; not sure what I was thinking when I used it in the example. – Alan Munn Feb 21 '23 at 04:49