2

I have a simple example here with three nodes and arrows connecting them, with labels on the arrows. However, I would like the labels to be vertically aligned (i.e., I want to move the 2 label up to have the same vertical position as the 1 label but still overlap its own arrow).

\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning,shapes}
\begin{document}
\begin{tikzpicture}
\node at (0,0) [rectangle,draw] (a) {$a$};
\node at (-1,-1) [rectangle,draw] (b) {$b$};
\node at (1,-2) [rectangle,draw] (c) {$c$};
\draw [->,>=latex] (a) -> node [] (l1) {1} (b);
\draw [->,>=latex] (a) -> node [] (l2) {2} (c);
\end{tikzpicture}
\end{document} 

first example

9
  • ?? Where did you get the syntax from ?? // However, why don't you forget about the labels and place two nodes where you need them, containing said description?
    – MS-SPO
    Nov 23, 2023 at 16:10
  • Because then I have to finetune the x-coordinate so that it overlaps the arrow. I would like it to figure this out automatically. Nov 23, 2023 at 16:17
  • 1
    There's no built-in placement for this. In this case at (intersection of l1--{[shift=(right:1)]l1 and a--c) would find the position you want. But it's not so easy with auto placement. Nov 23, 2023 at 16:21
  • @Qrrbrbirlbel, can you please explain where this code would fit into my example? Nov 23, 2023 at 16:28
  • 1
    You'd need something like \node at ...; i.e. place the node separately at the intersection of paths.
    – cfr
    Nov 23, 2023 at 16:32

4 Answers 4

5

The TikZ library intersections could be useful here. All that is needed is a 'helper' path extending horizontally from b that intersects the path from a to c -- placing '2' at the intersection finishes the figure. Easy, and fairly automatic. For specific instances, this approach will certainly require some adjustment.

By the way, the rectangle and circle shapes are always available without the shapes library, and rectangle is used by default for nodes. Saves a few keystrokes.

\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows,positioning,intersections}
\begin{document}
\begin{tikzpicture}
\node at (0,0) [draw] (a) {$a$};
\node at (-1,-1) [draw] (b) {$b$};
\node at (1,-2) [draw] (c) {$c$};
\draw [->,>=latex] (a) -> node [inner sep=1pt,fill=white] (l1) {1} (b);
\draw [name path=ac,->,>=latex] (a) -> (c)coordinate(c1);
\path [name path=tmppath] (l1) -- (l1 -| c1);% helper path to get intersection
\node [fill=white,inner sep=1pt,name intersections={of=tmppath and ac}] at (intersection-1) {2};
\end{tikzpicture}
\end{document} 

output

3

This drawing is an instructive example to do with Metapost -- the drawing language that is integrated with lualatex.

\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
beginfig(1);

  numeric u; u = 42;
  path a, b, c; 

  a = unitsquare shifted -(1/2, 1/2) scaled 1/3 u;
  b = a shifted (-u, -u);
  c = a shifted (u, -2u);

  forsuffixes s = a, b, c: 
    draw s;
    label("$" & str s & "$", center s);
  endfor

  ahangle := 30;
  drawarrow center a -- center b cutbefore a cutafter b;
  drawarrow center a -- center c cutbefore a cutafter c;

  z1 = 0.5 [center a, center b];
  z2 = whatever[center a, center c];
  y2 = y1;

  for i=1, 2:
    picture p; p = thelabel("$" & decimal i & "$", z[i]);
    unfill bbox p; draw p;
  endfor

endfig;
\end{mplibcode}
\end{document}

Compile this example with lualatex to produce a PDF that looks like this:

enter image description here

Notes

The approach here is to define three square <path> variables, a, b, and c shifted to the appropriate locations. Draw them and label them, then add the two arrows. The interesting bit is then this:

z1 = 0.5 [center a, center b];
z2 = whatever[center a, center c];
y2 = y1;

This defines two <pair> variables, z1 and z2. z1 is defined to be half way between the centre of a and the centre of b; z2 is defined to be somewhere along the line from the centre of a to the centre of c. Then in the third step the y-coordinate of z2 is set to be the same as the y-coordinate of z1. Which is what the OP wanted. MP allows you to have partial equations like this, provided only that all the points are defined before you try to draw them.

3

Code

\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows.meta} % “arrows” is deprecated
\makeatletter
\tikzset{
  on height of/.code={%
    \pgf@process{\tikz@scan@one@point\pgfutil@firstofone(#1)}\pgf@ya=\pgf@y
    \tikz@timer@start \pgf@yb=\pgf@y \tikz@timer@end \pgf@yc=\pgf@y
    \pgfmathsetmacro\tikz@time{(\pgf@ya-\pgf@yb)/(\pgf@yc-\pgf@yb)}}}
\makeatother

\tikzset{node on line/.style={inner sep=+.15em, fill=white}}
\begin{document}

%% manually via “intersection of”
\begin{tikzpicture}[> = Latex]
\path[nodes=draw] node at ( 0, 0) (a) {$a$}
                  node at (-1,-1) (b) {$b$}
                  node at ( 1,-2) (c) {$c$};
\path[->] (a) edge node (l1) {1} (b)
              edge               (c)
 node at (intersection of l1--{[xshift=1cm]l1} and a--c) (l2) {2};
\end{tikzpicture}

%% using “on height of”
\begin{tikzpicture}[> = Latex]
\path[nodes=draw] node at ( 0, 0) (a) {$a$}
                  node at (-1,-1) (b) {$b$}
                  node at ( 1,-2) (c) {$c$};
\path[->, nodes=node on line]
  (a) edge node                  (l1) {1} (b)
      edge node[on height of=l1] (l2) {2} (c);
\end{tikzpicture}

%% auto placement will need help
\begin{tikzpicture}[> = Latex, auto=right]
\path[nodes=draw] node at ( 0, 0) (a) {$a$}
                  node at (-1,-1) (b) {$b$}
                  node at ( 1,-2) (c) {$c$};
\path[->, inner sep=+.15em]
  (a) edge node                              (l1) {1} (b)
      edge node[swap, on height of=l1.south] (l2) {2} (c);
\end{tikzpicture}
\end{document}

Output

enter image description here

0

This approach is as good or bad as others:

  • use pos-parameter
  • determine its value as needed

I found pos=0.185 experimentally ... And as long as you can't read out the coordinates of (a), (b) etc. ...

result

\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows,shapes}
\begin{document}
 \begin{tikzpicture}[
    >=latex
 ]
    \node at ( 0, 0)    [rectangle,draw] (a) {$a$};
    \node at (-1,-1)    [rectangle,draw] (b) {$b$};
    \node at ( 1,-2)    [rectangle,draw] (c) {$c$};
    \draw [->] (a) -- node [pos=.5] (l1) {1} (b);
    \draw [->] (a) -- node [pos=.185] (l2) {2} (c);
 \end{tikzpicture}
\end{document} 

You must log in to answer this question.

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