7

I struggle positioning text above or below paths that I draw in TikZ.

Here is an example:

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{
  arrows,
  scopes,
  decorations.pathmorphing,
  decorations.markings}

\begin{document}  
\tikzstyle{doublepath}=
  [draw, line width=2mm, shorten >=4.9mm, shorten <=4.9mm,
   decoration={markings,
   mark=at position 0 with {\arrow[line width=1mm, scale=-1]{triangle 45}},
   mark=at position .999 with {\arrow[line width=1mm]{triangle 45}}},
   postaction={decorate}]
\tikzstyle{strength}=[midway,thin,inner sep=0,outer sep=0,sloped]

\begin{tikzpicture}[font=\sffamily]
  \path node[align=center] (A) {A};
  \path (0,6) node[align=center] (B) {B};
  \path (6,0) node[align=center] (C) {C};
  \path (6,6) node[align=center] (D) {D};

  \draw[doublepath,in=270-20,out=90+20] (A) to node [strength,below=2.36mm] {Label 1} (B) ;
  \draw[doublepath,in=270+20,out=90-20] (A) to node [strength,below=2.36mm] {Label 2} (B) ;
  \draw[doublepath,in=270-20,out=90+20] (C) to node [strength,below=2.36mm,pos=.49] {Label 1} (D) ;
  \draw[doublepath,in=270+20,out=90-20] (C) to node [strength,below=2.36mm,pos=.49] {Label 2} (D) ;
  \draw[doublepath,in=270+20,out=90-20] (C) to node [strength,below=2.36mm,pos=.51] {Label 3} (D) ;

  \draw[doublepath,in=180-20,out=0+20] (A) to node [strength,below=2.36mm,pos=.49] {Label 4} (C) ;
  \draw[doublepath,in=180-20,out=0+20] (A) to node [strength,below=2.36mm,pos=.51] {Label 5} (C) ;
  \draw[doublepath,in=180+20,out=0-20] (A) to node [strength,below=2.36mm] {Label 6} (C) ;

\end{tikzpicture}
\end{document}

enter image description here

The problem I encounter is that "above" and "below" seem to refer to the document (above = towards the top, below = towards the bottom) and not to the left or right side of the path that is drawn.

With a vertical path, above and below seem no longer defined. If the path is curved as in the example, a slight shift in position will flip the node text from one side to the other (Labels 2 and 3 in the example are at position 0.49 and 0.51). I understand the logic of this, but it does not help solve my problem. There are options left= and right=, but these will anchor the node differently and shift the label along the path.

(a related question is whether it is possible to have the text always with the baseline to the left, for example, regardless of whether it is above or below the path, relative to the path's direction. I tried rotate=180, but this also changes the distance to the path because the anchor is not in the middle).

How can I solve this problem? Ideally I'd like to have a possibility to place the text left or right for vertical paths, or specify the side of the text relative to the path's direction. Also, it would be great to be able to rotate the text so that all text is readable from the same side, regardless of whether the text is above or below a path. I am happy to do some fine tuning; however, currently it is really awkward because as soon as I change the direction or extent to which a predominantly vertical path is curved, the label may flip to the other side.

7

TikZ tries to intelligently interpret above and below. If you find this confusing, add the allow upside down key, then below will consistently mean the same side (the right side) of the path.

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{
  arrows,
  scopes,
  decorations.pathmorphing,
  decorations.markings}

\begin{document}  
\tikzset{doublepath/.style={draw, line width=2mm, shorten >=4.9mm, shorten <=4.9mm,
   decoration={markings,
   mark=at position 0 with {\arrow[line width=1mm, scale=-1]{triangle 45}},
   mark=at position .999 with {\arrow[line width=1mm]{triangle 45}}},
   postaction={decorate}},
  strength/.style={midway,thin,inner sep=0,outer sep=0,sloped}}

\begin{tikzpicture}[font=\sffamily,allow upside down]
  \path node[align=center] (A) {A};
  \path (0,6) node[align=center] (B) {B};
  \path (6,0) node[align=center] (C) {C};
  \path (6,6) node[align=center] (D) {D};

  \draw[doublepath,in=270-20,out=90+20] (A) to node [strength,below=2.36mm] {Label 1} (B) ;
  \draw[doublepath,in=270+20,out=90-20] (A) to node [strength,below=2.36mm] {Label 2} (B) ;
  \draw[doublepath,in=270-20,out=90+20] (C) to node [strength,below=2.36mm,pos=.49] {Label 1} (D) ;
  \draw[doublepath,in=270+20,out=90-20] (C) to node [strength,below=2.36mm,pos=.49] {Label 2} (D) ;
  \draw[doublepath,in=270+20,out=90-20] (C) to node [strength,below=2.36mm,pos=.51] {Label 3} (D) ;

  \draw[doublepath,in=180-20,out=0+20] (A) to node [strength,below=2.36mm,pos=.49] {Label 4} (C) ;
  \draw[doublepath,in=180-20,out=0+20] (A) to node [strength,below=2.36mm,pos=.51] {Label 5} (C) ;
  \draw[doublepath,in=180+20,out=0-20] (A) to node [strength,below=2.36mm] {Label 6} (C) ;

\end{tikzpicture}
\end{document}

enter image description here

And with this information it is easier to avoid collisions.

\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{
  arrows,
  scopes,
  decorations.pathmorphing,
  decorations.markings}

\begin{document}  
\tikzset{doublepath/.style={draw, line width=2mm, shorten >=4.9mm, shorten <=4.9mm,
   decoration={markings,
   mark=at position 0 with {\arrow[line width=1mm, scale=-1]{triangle 45}},
   mark=at position .999 with {\arrow[line width=1mm]{triangle 45}}},
   postaction={decorate}},
  strength/.style={midway,thin,inner sep=0,outer sep=0,sloped}}

\begin{tikzpicture}[font=\sffamily,allow upside down]
  \path node[align=center] (A) {A};
  \path (0,6) node[align=center] (B) {B};
  \path (6,0) node[align=center] (C) {C};
  \path (6,6) node[align=center] (D) {D};

  \draw[doublepath,in=270-20,out=90+20] (A) to node [strength,below=2.36mm] {Label 1} (B) ;
  \draw[doublepath,in=270+20,out=90-20] (A) to node [strength,below=2.36mm] {Label 2} (B) ;
  \draw[doublepath,in=270-20,out=90+20] (C) to node [strength,below=2.36mm,pos=.49] {Label 1} (D) ;
  \draw[doublepath,in=270+20,out=90-20] (C) to node [strength,below=2.36mm,pos=.49] {Label 2} (D) ;
  \draw[doublepath,in=270+20,out=90-20] (C) to node [strength,above=2.36mm,pos=.51] {Label 3} (D) ;

  \draw[doublepath,in=180-20,out=0+20] (A) to node [strength,above=2.36mm,pos=.49] {Label 4} (C) ;
  \draw[doublepath,in=180-20,out=0+20] (A) to node [strength,below=2.36mm,pos=.51] {Label 5} (C) ;
  \draw[doublepath,in=180+20,out=0-20] (A) to node [strength,below=2.36mm] {Label 6} (C) ;

\end{tikzpicture}
\end{document}

enter image description here

Please note that \tikzstyle is deprecated.

4

With bend left and bend right arrows and use of quotes package for edge labels:

\documentclass[tikz, margin=3mm]{standalone}
\usetikzlibrary{arrows.meta,
                positioning,
                quotes,
                }

\begin{document}
    \begin{tikzpicture}[
           node distance = 6cm,
       every edge/.style = {draw, line width=2mm, 
            {Triangle[length=5mm, width=5mm]}-{Triangle[length=5mm, width=5mm]},
            bend angle=20, shorten >=2mm, shorten <=2mm
                            },
every edge quotes/.style = {inner sep=2mm, font = \sffamily, auto=right, sloped},
                        ]  
\node (A)               {A};
\node (B) [above=of A]  {B};
\node (C) [right=of A]  {C};
\node (D) [above=of C]  {D};
%
\draw   (A) edge [bend left,  "Label 1"]                (B)
        (A) edge [bend right, "Label 2"]                (B)
        (A) edge [bend left,  "Label 5","Label 4" ']    (C)
        (A) edge [bend right, "Label 6"]                (C)
        (C) edge [bend left,  "Label 1" ']              (D)
        (C) edge [bend right, "Label 2","Label 3" ']    (D);
\end{tikzpicture}
\end{document}

where "Label 3 ' is equivalent to "Label 3" swap. This move Label 3 to opposite side of edge:

enter image description here

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.