Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I want to draw an arrow which passes over another arrow in a tikz-cd commutative diagram. I can do that as follows from the documentation:

\documentclass{article}
\usepackage{tikz-cd}
\begin{document}
\[
\begin{tikzcd}[ampersand replacement=\&,column sep=small]
  GM \arrow[pos=0.75]{rr}{\models_{M}}
     \arrow[two heads,swap]{dr}{e_{M}}
     \arrow[swap]{dd}{Gf}
     \&      \& 
     R^{FM}
       \arrow{dd}{R^{Ff}} \\
     \& T M 
    \arrow[tail,swap]{ru}{m_{M}}
    \arrow[swap,pos=0.75]{dd}{T f}
     \& \\
  GN \arrow[pos=0.75,crossing over]{rr}{\models_{N}}
     \arrow[two heads,swap]{dr}{e_{N}}
     \&      \& R^{FN} \\
     \& T N 
    \arrow[tail,swap]{ru}{m_{N}} \&    
\end{tikzcd}
\]
\end{document}  

Result

However, I want the arrow $Tf$ pass over the arrow $\models_{N}$. (I.e. the over and under crossing reversed). But as the arrow, which is supposed to be drawn over the other, is drawn before the other the `crossing over' option does not work.

I tried to use nodes for the entries in the diagram to be able to draw the arrow later (from node to node), but that gives me a compile error. I can always return to plain tikz, but I guess others using tikz-cd might find it also helpful to know how to use nodes or delay drawing an arrow. Any hint?

share|improve this question
    
To name a node inside a tikz matrix, you can use |[alias=something]| at the beginning of the cell. For instance, replace line 12 with "\& |[alias=TM]| T M" –  Florêncio Neves Mar 19 '13 at 1:43

2 Answers 2

up vote 5 down vote accepted

Like this?

Result

Although I must confess I don't have yet the general solution, for this particular case the effect was achieved by drawing the arrow from TN to TM instead of TM to TN. This way the arrow was drawn after the horizontal one. And of course I used leftarrow to get the arrowtip right.

\documentclass{article}
\usepackage{tikz-cd}
\begin{document}
\[
\begin{tikzcd}[ampersand replacement=\&,column sep=small]
  GM \arrow[pos=0.75]{rr}{\models_{M}}
     \arrow[two heads,swap]{dr}{e_{M}}
     \arrow[swap]{dd}{Gf}
     \&      \& 
     R^{FM}
       \arrow{dd}{R^{Ff}} \\
     \& T M 
    \arrow[tail,swap]{ru}{m_{M}}
     \& \\
  GN \arrow[pos=0.75,crossing over]{rr}{\models_{N}}
     \arrow[two heads,swap]{dr}{e_{N}}
     \&      \& R^{FN} \\
     \& T N 
    \arrow[leftarrow,pos=0.25,crossing over]{uu}{T f}  % <<----- HERE
    \arrow[tail,swap]{ru}{m_{N}} \&    
\end{tikzcd}
\]
\end{document}

Update: a more general solution

The above solution is ad-hoc and works only for this particular example. The general solution would allow to draw any additional arrow between two any nodes of the already typeset commutative diagram.

The idea is the following. Since internally tikzcd uses a matrix of nodes to typeset each node of the diagram, why wouldn't be possible to use those nodes as part of a path drawn after the diagram?

The idea is reasonable, but there are some issues here:

  1. What are the names of each node in the diagram? Would it be possible to use the syntax [(name)] normally allowed inside a tikz matrix of nodes? Answer: no it is not possible, that would break the code of the \arrow macro, which relies in the auto-generated names for the nodes.
  2. Then there are autogenerated names? Which are those names? Answer: They all begin with \tikzmatrixname and have the suffix -row-column. So for example, the first node of this diagram, (with label GM) would be \tikzmatrixname-1-1, the central node (TM) is \tikzmatrixname-2-2, and so on.
  3. So it would be possible to add \draw (\tikzmatrixname-1-1) to[bend left] (\tikzmatrixname-2-2); for example, after the matrix is done? i.e: this for example:

    \begin{tikzcd}[ampersand replacement=\&,column sep=small]
      GM \arrow[pos=0.75]{rr}{\models_{M}}
      [...]
      \arrow[tail,swap]{ru}{m_{N}} \&
    % After all nodes are in the matris, draw some extra arrows
    \draw[bend left] (\tikzmatrixname-1-1) to[bend left] (\tikzmatrixname-2-2);
    \end{tikzcd}
    

    Answer: Sadly, the answer is no, this is not possible because of the way tikcd handles the diagram. Inside the tikzcd environment, surprisingly enought, no tikz commands can be issued. Indeed, all tikz commands are undefined, because the tikzcd environment is not a tikzpicture environment. This explains why you cannot use \node, \draw nor any other command.

    What tikzcd does is, each time you use the command \arrow or other equivalent, to compute the appropiate \path command, but instead of "executing" it, it is stored in a list with all the other paths resulting from other \arrow commands. At the end of the tikzcd environment, a tikzpicture is created, which contains the matrix of nodes, and inside that picture, finally the list of \path commands is executed, drawing all the arrows.

So, what can we do?

It would be great if tikzcd provided a kind of \drawAtTheEnd command, which allows for storing any tikz drawing command in the same way that the list of paths, and execute that stored commands at the end of the tikzcd environment. This way we could add other arrows, decorations, define node coordinates with overlay, remember picture to be accessed from other parts of the page, etc.

In the meanwhile, I coded a hack which allows to insert a new path into the internal list used by tikzcd. The macro is called \latearrow and it takes four arguments:

  1. The tikz options of the arrow (you can pass colours, to paths, pos, etc
  2. The name of the starting node, without the \tikzmatrixnode part. I.e: to refer to GM node you will call it 1-1, the node TM will be 2-2, and so on.
  3. The name of the ending node (also without the \tikzmatrixnode part)
  4. The text for the label in the arrow.

Using that macro, you can first draw your complete commutative diagram except for the arrow from TM to TN, and then add that arrow at the end with the syntax:

\latearrow{pos=0.75,crossing over}{2-2}{4-2}{T f}

As said, it is a quick&dirty hack, and does not use the same syntax than other arrows, does not allow for style options for the label, and I'm not sure if it would break anything, but apparently it works. Here is the code:

\documentclass{article}
\usepackage{tikz-cd}

\makeatletter
\def\latearrow#1#2#3#4{%
  \toks@\expandafter{\tikzcd@savedpaths\path[/tikz/commutative diagrams/every arrow,#1]}%
  \global\edef\tikzcd@savedpaths{%
    \the\toks@%
    (\tikzmatrixname-#2)% \noexpand\tikzcd@sourceanchor)%
    to%
    node[/tikz/commutative diagrams/every label] {$#4$}
    (\tikzmatrixname-#3)% \noexpand\tikzcd@targetanchor)
;}}
\makeatother

\begin{document}
\[
\begin{tikzcd}[ampersand replacement=\&,column sep=small]
  GM \arrow[pos=0.75]{rr}{\models_{M}}
     \arrow[two heads,swap]{dr}{e_{M}}
     \arrow[swap]{dd}{Gf}
     \&      \& 
     R^{FM}
       \arrow{dd}{R^{Ff}} \\
     \& T M 
    \arrow[tail,swap]{ru}{m_{M}}
     \& \\
  GN \arrow[pos=0.75]{rr}{\models_{N}}
     \arrow[two heads,swap]{dr}{e_{N}}
     \&      \& R^{FN} \\
     \& T N 
    \arrow[tail,swap]{ru}{m_{N}} \&
\latearrow{pos=0.75,crossing over}{2-2}{4-2}{T f}
\latearrow{red, bend left}{1-1}{2-2}{x}
\end{tikzcd}
\]
\end{document} 

Note that I added a blue option to this arrow, to demonstrate that it works. Just for fun, I added also a red curved "late arrow" from GM to TM. This is the result:

Result

share|improve this answer
    
Yes, that is a solution. I wonder, however, why the \node command gives me error messages. The shown example proved to be too simple, I need to see if my other cases can be done this way too. Thanks for this fix. –  Bertfried Fauser Mar 16 '13 at 14:05
    
@BertfriedFauser I've updated my answer with a new hackish solution. –  JLDiaz Mar 18 '13 at 18:48
    
Regarding “\drawAtEnd”, isn't the key execute at end picture exactly what you are looking for? –  Florêncio Neves Mar 19 '13 at 2:00
    
It is indeed a bad idea to give a node a name, but you can give it an alias (see key /tikz/alias). Also, you can say \begin{tikzcd}[every matrix/.style={name=<name>}] to give the tikzcd matrix a specific name. (As you probably noticed, you can't use \tikzmatrixname in the to path parameter of an \arrow. The reason is that the argument to to path is only going to be expanded later, when the matrix has been finished and the value of \tikztomatrix forgotten. But you can certainly \global\let\somethingelse=\tikzmatrixname inside the tikzcd environment.) –  Florêncio Neves Mar 19 '13 at 13:44
    
@JLDiaz Thany oyu for the detailed explanation, that explains a lot, and most of the compile errors I got when trying stupid things. The \latearrow macro is great and will solve my other cases. I need to look at the other solutions, but that needs a few days. –  Bertfried Fauser Mar 19 '13 at 18:16

One approach here would be to break the arrow passing under into two pieces. Here are some ideas on how to do this:

One possibility is to use the fact that there is a matrix cell exactly at the point where you want one of the arrows to be broken:

\documentclass{article}
\usepackage{tikz-cd}
\begin{document}
\begin{tikzcd}[]
   & A \arrow{dd}   &   \\
     B \arrow[-]{r} & {} \arrow{r}{\phi} & C \\
   & D           & 
\end{tikzcd}
\end{document}

Alternatively, you can use the TikZ's perpendicular coordinate system (see pgf manual, section 13.3.1). In the example below, the arrow starting at B would land in D, but we modify the actual path drawn by saying to path={-- (\tikztostart -| \tikztotarget)} (the to path key is explained in section 14.14 of the pgf manual). This changes the endpoint of the arrow to be the intersection of a horizontal line through \tikztostart (in this case, the node containing B) and a vertical line through \tikztotarget (in this case, the node containing D). For the second piece of this arrow, we proceed similarly.

\documentclass{article}
\usepackage{tikz-cd}
\begin{tikzcd}[]
  &
    A \arrow{dd}
      & \\
  B \arrow[-,
           shorten >=0.7ex,
           to path={-- (\tikztostart -| \tikztotarget)}]
          {rd}
    &
      &
        C \\
   &
     D \arrow[shorten <=0.7ex,
              to path={(\tikztostart |- \tikztotarget)
                         -- (\tikztotarget) \tikztonodes}]
             {ru}
             {\phi}
       &
\end{tikzcd}
\end{document}

Finally, a generalization of the above for possibly slanted or curved lines can be achieved using the intersections library (section 13.3.2 of the pgf manual). I hope the example below will be self-explaining.

\documentclass{article}
\usepackage{tikz-cd}
\usetikzlibrary{intersections}
\begin{tikzcd}
  A \arrow[name path=above]{rd}
    & B \arrow[name path=below, draw=none]{ld}
        \arrow[name intersections={of=above and below},
               -,
               shorten >=0.7ex,
               to path={-- (intersection-1)}]{}
        \arrow[shorten <=0.7ex,
               to path={(intersection-1) -- (\tikztotarget) \tikztonodes}]
              {ld}{\phi}
    \\
  C
    & D
\end{tikzcd}
\end{document}
share|improve this answer
    
I like the last one, as I have crossings which are not at matrix nodes. –  Bertfried Fauser Mar 19 '13 at 18:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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