8

I want to draw labeled parallel arrow in commutative diagram with TikZ, I searched on google and Tex Stackexchange, however, I found only the method to draw parallel arrow by transform canvas only, I tried to add the labeled but it failed.

Here is my picture:

enter image description here

I want to label a map from $\mathfrak{P}=\bigoplus_{i\inI}\mathfrak{P_{i}}$ to $\mathfrak{P_{i}}$ and from $\mathfrak{P_{i}}$ to $\mathfrak{P}=\bigoplus_{i\inI}\mathfrak{P_{i}}$, i.e the arrows of the square.

Here is the code :

\begin{tikzpicture}[node distance=2.8cm, auto]
\node (P) {$\mathfrak{P}=\bigoplus_{i\in I}\mathfrak{P_{i}}$};
\node(Q)[right of=P] {$\mathfrak{P_{j}}$};
\node (B) [below of=P] {$\mathfrak{B}$};
\node (C) [right of=B] {$\mathfrak{C}$};
\draw[transform canvas={yshift=0.5ex},->] (P) - -(Q);
\draw[transform canvas={yshift=-0.5ex},->](Q) -- (P); 
\draw[->](Q) to node {$a$}(B);
\draw[->](Q) to node {$a$}(C);
\draw[->] (P) to node {$\pi_{j}$} (B);
\draw[->] (B) to node {$\psi$} (C);
\draw[->, dashed] (Q) to node [swap] {$g$} (B);
\end{tikzpicture}
1
  • @percusse: Thank you for helping me editing my post. Mar 16, 2012 at 4:59

3 Answers 3

8

Here are your labeled lines.

There are other ways to shift nodes but IMO the transform canvas is the most direct, so you are doing fine for that aspect.

To label a line, you can add a node command at the end of the line specification. The label may be placed above or below and you can specify where along the line with keywords such as midway or the more general pos=<fraction along line>. I also shifted the diagonal lines so that they may both be seen (since one was dashed).

I added a macro to simplify the shifting of the diagonal lines.

\documentclass[border=5pt]{standalone}

\usepackage{amsmath,amssymb}

\usepackage{tikz}
\usetikzlibrary{calc}


\begin{document}

\begin{tikzpicture}[node distance=2.8cm, auto]

\pgfmathsetmacro{\shift}{0.3ex}

\node (P) {$\mathfrak{P}=\bigoplus_{i\in I}\mathfrak{P_{i}}$};
\node(Q)[right of=P] {$\mathfrak{P_{j}}$};
\node (B) [below of=P] {$\mathfrak{B}$};
\node (C) [right of=B] {$\mathfrak{C}$};

\draw[transform canvas={yshift=0.5ex},->] (P) --(Q) node[above,midway] {\tiny top};
\draw[transform canvas={yshift=-0.5ex},->](Q) -- (P) node[below,midway] {\tiny bottom}; 
\draw[->](Q) to node {$a$}(C);
\draw[->] (P) to node[swap] {$\pi_{j}$} (B);
\draw[->,dashed] (B) to node {$\psi$} (C);

\draw[->,transform canvas={xshift=-\shift,yshift=\shift}](Q) to node {$a$}(B);
\draw[->, dashed,transform canvas={xshift=\shift,yshift=-\shift}] (Q) to node[swap] {$g$} (B);

\end{tikzpicture}

\end{document}

enter image description here

6
  • ([yshift=...]P)--([yshift=...]Q) is also an option.
    – percusse
    Mar 16, 2012 at 4:06
  • @percusse: you are correct, but I think that that method is more appropriate when you are shifting each point by a different amount.
    – Frédéric
    Mar 16, 2012 at 4:18
  • 1
    With transform canvas one runs into two problems (not in this case, though): the bounding box is not correct, and any positions saved whilst under the influence will not be correct (try labelling the top to see). However, when I tried percusse's method, I got strange results. To get the right result, I had to add the anchor: ([yshift=2.5ex]P.east) -- ([yshift=2.5ex]Q.west). Mar 16, 2012 at 7:43
  • I agree with Andrew for transform canvas. This option is sometimes dangerous (see the pgfmanual). Now ([yshift=...]P)--([yshift=...]Q) (remark from percusse) is wrong. You need to use P.east and Q.west. But for the arrow between Q and C, transform canvas is useful to get something elegant (similar arrows) Mar 16, 2012 at 8:20
  • @AndrewStacey xshift and yshift works with coordinates Mar 16, 2012 at 8:26
8

Perhaps to clarify some points.

1) First ([yshift=...]P)--([yshift=...]Q) does not work. Example:

\documentclass{scrartcl}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}
  \node(A) at (0,0) {A};   \node(B) at (5,0) {B};
   \draw[green] (A) -- (B);
   \draw [yellow,yshift=.5 cm] (0,0) -- (5,0);
   \draw[blue,yshift=1 cm] (A) -- (B); %problem
   \draw[red] ([yshift=1 cm]A) -- ([yshift=1 cm]B);  %problem
   \draw[magenta] ([yshift=1 cm]A.east) -- ([yshift=1 cm]B.west);     
\end{tikzpicture}   

\begin{tikzpicture}
  \coordinate(A) at (0,0) ;   \coordinate(B) at (5,0);
  \draw (A) -- (B);
  \draw[red] ([yshift=.5 cm]A) -- ([yshift=.5 cm]B);  %fine 
  \draw[blue,yshift=1 cm] (A) -- (B); %problem    
\end{tikzpicture} 
\end{document}

enter image description here

2) About transform canvas

Canvas transformations should be used with great care. In most circumstances you do not want line widths to change in a picture as this creates visual inconsistency. Just as important, when you use canvas transformations pgf loses track of positions of nodes and of picture sizes since it does not take the effect of canvas transformations into account when it computes coordinates of nodes (do not, however, rely on this; it may change in the future). Finally, note that a canvas transformation always applies to a path as a whole, it is not possible (as for coordinate transformations) to use different transformations in different parts of a path. In short, you should not use canvas transformations unless you really know what you are doing.

I think it's better to avoid it

3) I remove right of etc. because i like to scale my pictures when it's necessary

right of seems to be more concise but you need to fix node distance=... and to write right of=P at (5,0) is more concise or `--++(5,0)``

\documentclass{scrartcl}    
\usepackage{amsmath,amssymb}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}

\begin{tikzpicture}[auto,scale=2]

\node (P) at (0,0)  {$\mathfrak{P}=\bigoplus_{i\in I}\mathfrak{P_{i}}$};
\node (Q) at (3,0)  {$\mathfrak{P_{j}}$};
\node (B) at (0,-3) {$\mathfrak{B}$};
\node (C) at (3,-3) {$\mathfrak{C}$};    


\draw[->] ([yshift =  .3ex]P.east)  --  node[above] {\tiny top}     
          ([yshift =  .3ex]Q.west) ;
\draw[<-] ([yshift = -.3ex]P.east) --  node[below] {\tiny bottom}  
          ([yshift = -.3ex]Q.west); 
\draw[->](Q) to node {$a$}(C);
\draw[->] (P) to node[swap] {$\pi_{j}$} (B);
\draw[->,dashed] (B) to node {$\psi$} (C);  

\draw[->]    ( Q.south west)  -- node[above] {$a$}
             ( B.north east) ; 

\draw[->,dashed] ([xshift= 0.2ex ,yshift = - 0.3ex ] Q.south west) -- node[below] {$g$} 
                 ([xshift=  0.2ex ,yshift = - 0.3ex ]B.north east);

\end{tikzpicture}
\end{document} 

enter image description here

2
  • Wow, that's a strange output. I learned yet another subtle detail thanks to you.
    – percusse
    Mar 16, 2012 at 16:21
  • There are a lot of strange outputs and subtle details with TeX and TikZ ! With my old neurons, I forget many of these details every day. Mar 16, 2012 at 17:11
7

You might also want to have a look at the rather new package tikz-cd.

Its command \arrow has a mandatory argument identifying the direction, e.g. r for “right”. It also has an optional argument to specify TikZ options like transform canvas. It also has further argument pairs (optional and “mandatory” ) for labels.

  • An arrow pointing right: \arrow{r}
  • An arrow pointing right with label above: \arrow{r}{label}
  • An arrow pointing right with label below: \arrow{r}[swap]{label}
  • An arrow pointing right and shifted: \arrow[transform canvas={yshift=.5ex}]{r}

Here's a complete try:

\documentclass{article}
\usepackage{amsmath,amssymb}
\usepackage{tikz-cd}

\begin{document}

\begin{tikzcd}[row sep=3cm,column sep=2.5cm]
   \mathfrak{P}=\bigoplus_{i\in I}\mathfrak{P_{i}}
     \arrow[transform canvas={yshift=.5ex}]{r}
     \arrow[transform canvas={yshift=-.5ex},leftarrow]{r}
     \arrow{d}[swap]{\pi_{j}}
 & \mathfrak{P_{j}}
     \arrow{d}{a}
     \arrow[transform canvas={yshift=.3ex,xshift=-.3ex}]{ld}[swap]{g}
     \arrow[transform canvas={yshift=-0.3ex,xshift=.3ex},dashed]{ld}{a} \\
     \mathfrak{B}
     \arrow{r}{\psi}
 & \mathfrak{C}
\end{tikzcd}

\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .