# Arrow to arrow and shorter (?) arrows

I have been spending a lot of time trying to generate a nice looking graphical representation of hypotheses, but I can't seem to get it right.. The main problem is that I don't see how to let an arrow (caption H8) point from node H to the middle of the arrow between F and G. I also want then another arrow (caption H9) to point from node I to the arrow just created point from H to the arrow between F and G. Another issue is that I think that the arrows look a bit weird atm (should they be shorter and not 'touch' the nodes?). This is what it looks like right now:

And this is my current code without those two arrows in it:

\documentclass{article}
\usepackage[english]{babel}
\usepackage{tikz}
\usetikzlibrary{positioning}
\tikzset{main node/.style={rectangle,fill=white!5,draw,minimum size=1cm,inner sep=4pt},
}

\begin{document} \centering \begin{tikzpicture}

\node[main node] (A) at (0,3) {Situation};
\node[main node] (B) at (3,1) {Gratitude};
\node[main node] (C) at (3,3) {Guilt};
\node[main node] (D) at (3,5) {Anger};
\node[main node] (F) at (6,3) {State};
\node[main node] (G) at (9,3) {Actions};
\node[main node] (H) at (7.5,0) {Higher order beliefs};
\node[main node] (I) at (9,1.5) {Time pressure};
\draw [->] (A) -- node[below] {H3} (B);

\draw [->] (A) -- node[below] {H2} (C);

\draw [->] (A) -- node[above] {H1} (D);

\draw [->] (B) -- node[below] {H6} (F);

\draw [->] (C) -- node[below] {H5} (F);

\draw [->] (D) -- node[above] {H4} (F);

\draw [->] (F) -- node[above] {H7} (G);
\end{tikzpicture}
\end{document}


You can define points between nodes like this:

\draw [->] (F) -- coordinate[pos=0.2] (fg) (G);


This defines a coordinate named fg between F and G; pos=0 means at F, pos=1 means at G, and pos=0.2 is a position quite close to F. Omitting the option is the same as pos=0.5, i.e., the coordinate would be placed midway between the two nodes.

You can specify positions that are above/below/left/right of other nodes using -| and |-. The position (A-|B) is horizontally left/right of A and vertically above/below of B.

Shortening of arrows can be achieved with the options shorten <=2pt (shortens the start of arrows by 2pt) and shorten >=2pt (shortens the end of arrows by 2pt). Adding it to the tikzpicture affects all lines, adding it to the options of a \draw command affects only specific lines.

\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\tikzset
{main node/.style=
{rectangle,fill=white!5,draw,minimum size=1cm,inner sep=4pt}
}
\begin{document}
\begin{tikzpicture}%
[shorten <=2pt,shorten >=2pt,>=stealth]
\node[main node] (A) at (0,3) {Situation};
\node[main node] (B) at (3,1) {Gratitude};
\node[main node] (C) at (3,3) {Guilt};
\node[main node] (D) at (3,5) {Anger};
\node[main node] (F) at (6,3) {State};
\node[main node] (G) at (9,3) {Actions};
\node[main node] (H) at (7.5,0) {Higher order beliefs};
\node[main node] (I) at (9,1.5) {Time pressure};
\draw [->] (A) -- node[below] {H3} (B);
\draw [->] (A) -- node[below] {H2} (C);
\draw [->] (A) -- node[above] {H1} (D);
\draw [->] (B) -- node[below] {H6} (F);
\draw [->] (C) -- node[below] {H5} (F);
\draw [->] (D) -- node[above] {H4} (F);
\draw [->] (F) -- node[above] {H7} coordinate[pos=0.2] (fg) (G);
\draw [<-] (fg) --node[left] {H8} coordinate (fgH) (fg|-H.north);
\draw [->] (I.west) -- node[above] {H9} (I.west-|fgH);
\end{tikzpicture}
\end{document}


Edit Regarding the question in the comments: There are several methods to position edge labels.

You can add a distance to above, below etc.

\draw [->] (A) -- node[below=3mm] {H2} (C);


You can use xshift and/or yshift to move the node:

\draw [->] (C) -- node[below,xshift=-5mm] {H5} (F);


You can change the inner or outer separation, this is the extra space surrounding the border of the node.

\draw [->] (A) -- node[below,outer sep=2pt] {H3} (B);
\draw [->] (A) -- node[above,inner sep=7pt] {H1} (D);


You can place the node without contents directly on the line and add the contents as a label to the node.

\draw [->] (D) -- node[label=H4] {} (F);
\draw [->] (D) -- node[label=90:H4] {} (F);
\draw [->] (B) -- node[label={[label distance=1cm]-90:H6}] {} (F);


The first two lines are equivalent: If no direction is given, the default is above, i.e., 90 degrees. Additionally, the label distance can be specified as an option. Note that you need extra braces if the value of the option label contains square brackets, commas, or equality signs.

In the example below I have added the draw option to show the border and the position of the nodes.

\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\tikzset
{main node/.style=
{rectangle,fill=white!5,draw,minimum size=1cm,inner sep=4pt}
}
\begin{document}
\begin{tikzpicture}%
[shorten <=2pt,shorten >=2pt,>=stealth]
\node[main node] (A) at (0,3) {Situation};
\node[main node] (B) at (3,1) {Gratitude};
\node[main node] (C) at (3,3) {Guilt};
\node[main node] (D) at (3,5) {Anger};
\node[main node] (F) at (6,3) {State};
\draw [->] (A) -- node[below,outer sep=2pt,draw] {H3} (B);
\draw [->] (A) -- node[below=3mm,draw] {H2} (C);
\draw [->] (A) -- node[above,inner sep=7pt,draw] {H1} (D);
\draw [->] (B) -- node[label={[label distance=1cm]-90:H6},draw] {} (F);
\draw [->] (C) -- node[below,xshift=-5mm,draw] {H5} (F);
\draw [->] (D) -- node[label=H4,draw] {} (F);
\end{tikzpicture}
\end{document}

• One more question: how can I put in a bit more space in between H1, H3, H4 and H6 and the arrow? Because right now that are practically touching the arrow and I'd like a bit of space in between – Inge Apr 24 '17 at 12:53
• @Inge See the edit of my answer. – gernot Apr 24 '17 at 16:10

A quick method for making the existing arrows shorter is to add some outer sep to the main nodes.

For the missing arrows, you can give a name to the node that is midway along the arrow, and use that as a starting point.

\documentclass{article}
\usepackage[english]{babel}
\usepackage{tikz}
\usetikzlibrary{positioning}
\tikzset{
main node/.style={rectangle,fill=white!5,draw,minimum size=1cm,inner sep=4pt,outer sep=2pt}
}
\begin{document}
\centering
\begin{tikzpicture}

\node[main node] (A) at (0,3) {Situation};
\node[main node] (B) at (3,1) {Gratitude};
\node[main node] (C) at (3,3) {Guilt};
\node[main node] (D) at (3,5) {Anger};
\node[main node] (F) at (6,3) {State};
\node[main node] (G) at (9,3) {Actions};
\node[main node] (H) at (7.5,0) {Higher order beliefs};
\node[main node] (I) at (9,1.5) {Time pressure};

\draw [->] (A) -- node[below] {H3} (B);
\draw [->] (A) -- node[below] {H2} (C);
\draw [->] (A) -- node[above] {H1} (D);
\draw [->] (B) -- node[below] {H6} (F);
\draw [->] (C) -- node[below] {H5} (F);
\draw [->] (D) -- node[above] {H4} (F);
\draw [->] (F) -- node[above] (FG) {H7} (G);

\draw [->,shorten >=2pt] (H) to[bend left] node[left] (FGH) {H8} (FG);
\draw [->] (I) -- node[above] {H9} (FGH);
\end{tikzpicture}
\end{document}


Based on *Torbjørn T.\$ answer, but with use of quotes package for edge labeling, package positioning for nodes positioning and with some effort to make code shorter:

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

\begin{document}
\centering
\begin{tikzpicture}[auto,
node distance = 6mm and 15 mm,
main node/.style = {rectangle, draw, minimum size=1cm,
inner sep=4pt, outer sep=2pt}
]
\begin{scope}[every node/.style={main node}]
\node  (A) {Situation};
\node[right=of A]   (C) {Guilt};
\node[below=of C]   (B) {Gratitude};
\node[above=of C]   (D) {Anger};
\node[right=of C]   (F) {State};
\node[right=of F]   (G) {Actions};
\node[below=of G]   (I) {Time pressure};
\node[below=of I.south west]    (H) {Higher order beliefs};
\end{scope}
\draw[->]   (A) edge ["H3" '] (B)
(A) edge ["H2"] (C)
(A) edge ["H1"] (D)
(B) edge ["H6"'] (F)
(C) edge ["H5"] (F)
(D) edge ["H4"] (F)
(F) edge node[above] (FG) {H7} (G);
\draw [->,shorten >=2pt]
(H) edge [bend left] node[left] (FGH) {H8} (FG)
(I)  to ["H9" '] (FGH.east |- I);
\end{tikzpicture}
\end{document}