9

I'm using tikzmark to define some arrows to point to variables in an equation.

\documentclass{article}

\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{tikz}
\usetikzlibrary{tikzmark}

\begin{document}
A \emph{complex number} is an expression of the form
\[
  z = \tikzmark{b}b\cdot\tikzmark{i}i+\tikzmark{a}a
  \begin{tikzpicture}[
    , line join=round
    , line cap=round
    , remember picture
    , overlay
    ]

    \draw[<-, thick]
    ([shift={(3pt,-2pt)}]pic cs:b) |- ([shift={(-10pt, -10pt)}]pic cs:b)
    node[anchor=east] {``imaginary part'' $\Im(z)\in\mathbb{R}$};

    \draw[<-, thick]
    ([shift={(4pt,-2pt)}]pic cs:i) |- ([shift={(-15pt,-25pt)}]pic cs:i)
    node[anchor=east] {``imaginary unit'' $i^2=-1$};

    \draw[<-, thick]
    ([shift={(4pt,-2pt)}]pic cs:a) |- ([shift={(15pt,-25pt)}]pic cs:a)
    node[anchor=west] {``real part'' $\Re(z)\in\mathbb{R}$};
  \end{tikzpicture}
\]
%The collection of complex numbers is denoted by $\mathbb{C}$.
\end{document}

enter image description here

My problem is that uncommenting the text after the equation produces:

enter image description here

The picture runs into the text! Is this fixable?

0
6

AFAIK there is no general simple solution since you use (and have to use) an overlay picture, which, by definition, disables the bounding box. What you can do, however, is to measure the space the nodes take with calc and insert it.

\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{tikz}
\usetikzlibrary{tikzmark,calc,fit}

\begin{document}
A \emph{complex number} is an expression of the form
\[
  z = \tikzmark{b}b\cdot\tikzmark{i}i+\tikzmark{a}a
  \begin{tikzpicture}[
    , line join=round
    , line cap=round
    , remember picture
    , overlay
    ]

    \draw[<-, thick]
    ([shift={(3pt,-2pt)}]pic cs:b) |- ([shift={(-10pt, -10pt)}]pic cs:b)
    node[anchor=east](a) {``imaginary part'' $\Im(z)\in\mathbb{R}$};

    \draw[<-, thick]
    ([shift={(4pt,-2pt)}]pic cs:i) |- ([shift={(-15pt,-25pt)}]pic cs:i)
    node[anchor=east](b) {``imaginary unit'' $i^2=-1$};

    \draw[<-, thick]
    ([shift={(4pt,-2pt)}]pic cs:a) |- ([shift={(15pt,-25pt)}]pic cs:a)
    node[anchor=west](c) {``real part'' $\Re(z)\in\mathbb{R}$};
    \node[fit=(a)(b)(c),inner sep=0pt](f){};
    \path let \p1=($(pic cs:a)-(f.south)$) in
    \pgfextra{\xdef\myh{\y1}};
  \end{tikzpicture}
\vspace*{\myh}
\]
The collection of complex numbers is denoted by $\mathbb{C}$.
\end{document}

enter image description here

P.S. I is not completely inconceivable to let TikZ record the would-be bounding box, but this would require major surgery.

4
  • Good approach by measuring the missing space!! What do you mean in the P.S? – manooooh Oct 30 '19 at 4:08
  • 1
    @manooooh The TikZ bounding box is obtained by recording all coordinates, and then adding the correct box. If you use overlay, no box is added, but one could still ask TikZ to record all coordinates and anchors, and to store them somewhere such that one may use them. – user194703 Oct 30 '19 at 4:13
  • 1
    I mean what do you mean in the first two words of the P.S. section... :P – manooooh Oct 30 '19 at 4:13
  • 1
    Oh, thanks! Yes, there is a typo.I is should be It is. Cat paws are not fool safe.;-) – user194703 Oct 30 '19 at 4:16
6

In order to avoid this overlap, it is possible to write the expression of the complex number in a node. And with the \subnode command of the tikzmark package to create subnodes within it. But since \subnode doesn't position the arrows perfectly, I prefer to use the \tikzmarknode command instead, which centers them perfectly.

I used the hv path style with the bold arrow defined on page 74 of the tikz manual to draw the arrows at right angles with an edge operation.

hv path/.style={-{>[sep]},thick,to path={-| (\tikztotarget)}}

For a reason that I don't understand, it is necessary to keep the remember picture option (but without the overlay option). If an expert can explain why I would be interested to know.

screenshot

I commented without deleting your original code which is now useless.

\documentclass{article}

\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{tikz}
\usetikzlibrary{tikzmark,positioning}

\begin{document}
A \emph{complex number} is an expression of the form

  \begin{tikzpicture}[
    , line join=round
    , line cap=round
    ,hv path/.style={-{>[sep]},thick,to path={-| (\tikztotarget)}}
    ,remember picture
 %   , overlay
    ]
\node (z) at (5,0) {$  z = \tikzmarknode{b}{b}\cdot\tikzmarknode{i}{i}+\tikzmarknode{a}{a}$};

%    \draw[<-, thick]   
%    ([shift={(3pt,-2pt)}]pic cs:b) |- ([shift={(-10pt, -10pt)}]pic cs:b)
    \node[below left = 0mm and 0mm of z] (i-part) {``imaginary part'' $\Im(z)\in\mathbb{R}$} edge[hv path] (pic cs:b);

%    \draw[<-, thick]
%    ([shift={(4pt,-2pt)}]pic cs:i) |- ([shift={(-15pt,-25pt)}]pic cs:i)
    \node[below = 0mm of i-part] (i-unit) {``imaginary unit'' $i^2=-1$}edge[hv path] (pic cs:i);

%    \draw[<-, thick]
%    ([shift={(4pt,-2pt)}]pic cs:a) |- ([shift={(15pt,-25pt)}]pic cs:a)
    \node[right = 2.5cm of i-unit] {``real part'' $\Re(z)\in\mathbb{R}$}edge[hv path] (pic cs:a);
    \end{tikzpicture}

The collection of complex numbers is denoted by $\mathbb{C}$.
\end{document}
7
  • Using a \tikzmarknode in a \node nests tikzpictures. It is most strongly recommended not nesting tikzpictures. – user194703 Oct 30 '19 at 4:14
  • The question is why it is not recommended and why it works perfectly here without any problems. What does @loopspace think about the insertion of tikzmarknode in a tikz node? – AndréC Oct 30 '19 at 6:57
  • LoopSpace has a very clear opinion. It "works perfectly" in this example by sheer accident. Once you add keys, problems start to arise. – user194703 Oct 30 '19 at 11:32
  • Loopspace talks about the interweaving of TikZ's standard environment, the tikzmark environment is not standard. Instead of saying that this is an accident, prove it with a counter-example. – AndréC Oct 30 '19 at 11:44
  • Nope. Do not read something in LoopSpace's post which is not there. Please read the post again, and try e.g. \node[rotate=10] (z) at (5,0) {$ z = \tikzmarknode{b}{b}\cdot\tikzmarknode{i}{i}+\tikzmarknode{a}{a}$}; (Yes, you can fix it somehow, but this is precisely the point: you need to add a lot of extra stuff just because you nested tikzpictures, and there is really no need to.) – user194703 Oct 30 '19 at 11:52
3

Alternatively, one can fake the overlay horizontally by saving the dimensions.

Note that [remember picture] works by recording the origin location in the aux file. Overlay places the origin at the current baseline/tikzpicture location.

\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{tikz}
\usetikzlibrary{tikzmark,calc,fit}

\newsavebox{\mybox}% global
\newlength{\myleft}
\newlength{\myright}

\begin{document}
A \emph{complex number} is an expression of the form
\savebox{\mybox}{\begin{tikzpicture}[
    , line join=round
    , line cap=round
    , remember picture
    , baseline=(origin)
    ]
    \coordinate (origin) at (0,0);

    \draw[<-, thick]
    ([shift={(3pt,-2pt)}]pic cs:b) |- ([shift={(-10pt, -10pt)}]pic cs:b)
    node[anchor=east] {``imaginary part'' $\Im(z)\in\mathbb{R}$};

    \draw[<-, thick]
    ([shift={(4pt,-2pt)}]pic cs:i) |- ([shift={(-15pt,-25pt)}]pic cs:i)
    node[anchor=east] {``imaginary unit'' $i^2=-1$};

    \draw[<-, thick]
    ([shift={(4pt,-2pt)}]pic cs:a) |- ([shift={(15pt,-25pt)}]pic cs:a)
    node[anchor=west] {``real part'' $\Re(z)\in\mathbb{R}$};

    \pgfextractx{\myleft}{\pgfpointanchor{current bounding box}{west}}
    \global\myleft=\myleft
    \pgfextractx{\myright}{\pgfpointanchor{current bounding box}{east}}
    \global\myright=\myright
\end{tikzpicture}}
\[
  z = \tikzmark{b}b\cdot\tikzmark{i}i+\tikzmark{a}a
  \hspace{\myleft}\usebox\mybox\hspace{-\myright}
\]
The collection of complex numbers is denoted by $\mathbb{C}$.
\end{document}
3

Here are two other solutions.

In the first solution, I remove the overlay option from your tikzpicture and compute the depth of yours annotations (the distance between the top of first node and the bottom of the last node).

\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{tikz}
\usetikzlibrary{calc,tikzmark}
\begin{document}
A \emph{complex number} is an expression of the form
\[
  z = \tikzmark{b}b\cdot\tikzmark{i}i+\tikzmark{a}a
\begin{tikzpicture}[
  , line join=round
  , line cap=round
  , remember picture
  , baseline=0 % to compute depth...
  ]
  \begin{scope}[overlay]
    \draw[<-, thick] ([shift={(3pt,-2pt)}]pic cs:b) |- ([shift={(-10pt, -10pt)}]pic cs:b)
    node[anchor=mid east] (a) {``imaginary part'' $\Im(z)\in\mathbb{R}$};

    \draw[<-, thick] ([shift={(4pt,-2pt)}]pic cs:i) |- ([shift={(-15pt,-25pt)}]pic cs:i)
    node[anchor=mid east] {``imaginary unit'' $i^2=-1$};

    \draw[<-, thick] ([shift={(4pt,-2pt)}]pic cs:a) |- ([shift={(15pt,-25pt)}]pic cs:a)
    node[anchor=mid west] (b) {``real part'' $\Re(z)\in\mathbb{R}$};\
  \end{scope}
  \path let \p1=(a.north west), \p2=(b.south east) in  (0,0) -- (0,\y2-\y1);
\end{tikzpicture}
\]

The collection of complex numbers is denoted by $\mathbb{C}$.
\end{document}

The second solution uses \tikzmarknode and fit to compute the math targets with margins then positions the commentary nodes with the same margins and finally draws the arrows. The syntax is more regular: no shift and just two distances (the 2pt margin and the 1em horizontal shifting).

\documentclass{article}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{tikz}
\usetikzlibrary{calc,tikzmark,fit}
\begin{document}
A \emph{complex number} is an expression of the form
\begin{equation}
  z = \tikzmarknode{b}{b}\cdot\tikzmarknode{i}{i}+\tikzmarknode{a}{a}
\begin{tikzpicture}[
  , line join=round
  , line cap=round
  , remember picture
  , baseline=0 % to compute depth
  ]
  \begin{scope}[overlay]
    \tikzset{
      text node/.style={inner sep=2pt},
      fitmath/.style={node contents={},text node,fit=#1},
    }
    % math target nodes
    \node[fitmath=(b),name=bt];
    \node[fitmath=(i),name=it];
    \node[fitmath=(a),name=at];
    % commentary nodes
    \path (bt.south) ++ (-1em,0)
    node[text node,anchor=north east] (bc) {``imaginary part'' $\Im(z)\in\mathbb{R}$};
    \path (bc.south east)
    node[text node,anchor=north east] (ic) {``imaginary unit'' $i^2=-1$};
    \path (ic.mid -| at) ++ (1em,0)
    node[text node,anchor=mid west] (ac)   {``real part'' $\Re(z)\in\mathbb{R}$};
    % arrows between nodes
    \draw[<-, thick] (bt.south) |- (bc.mid east);
    \draw[<-, thick] (it.south) |- (ic.mid east);
    \draw[<-, thick] (at.south) |- (ac.mid west);
  \end{scope}
  \path let \p1=(a.south), \p2=(ac.south) in  (0,0) -- (0,\y2-\y1);
\end{tikzpicture}
\end{equation}

The collection of complex numbers is denoted by $\mathbb{C}$.
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.