# TikZ: How to draw an arrow in the middle of the line?

Like this:

.------<------.
|             |
v             ^
|             |
'------>------'


I am currently using

\begin{scope}[very thick,->]
\draw (-4,1)--(-4,0)--(0.1,0);
\draw (0,0)--(4,0)--(4,1.1);
\draw (4,1)--(4,2)--(-0.1,2);
\draw (0,2)--(-4,2)--(-4,0.9);
\end{scope}


but this is rather inelegant. I prefer something more like

\begin{scope}[very thick,middle decoration=>]
%           ^^^^^^^^^^^^^^^^^ a hypothetical option
\draw (-4,0)--(4,0);
\draw (4,0)--(4,2);
\draw (4,2)--(-4,2);
\draw (-4,2)--(-4,0);
\end{scope}

-

The decorations library can be used to all kinds of stuff like this. Unfortunately it is slightly verbose.

\usetikzlibrary{decorations.markings}

\begin{scope}[very thick,decoration={
markings,
mark=at position 0.5 with {\arrow{>}}}
]
\draw[postaction={decorate}] (-4,0)--(4,0);
\draw[postaction={decorate}] (4,0)--(4,2);
\draw[postaction={decorate}] (4,2)--(-4,2);
\draw[postaction={decorate}] (-4,2)--(-4,0);
\end{scope}

-
But with a few every path/.style={}s then it shouldn't be too wordy. Nice! (Better than mine) –  Andrew Stacey Sep 16 '10 at 20:56
@Andrew When I put postaction={decorate} into the every path/.style={}, I get an error: Undefined control sequence. \pgf@decorate@processnextinputsegmentobject. I have no idea why. –  Caramdir Sep 16 '10 at 21:09
Hm, it also says "I cannot decorate an empty path". Is it possible that pgf is trying to apply the decoration even to the paths that the arrow is made from, and one of the paths is empty? –  Jan Hlavacek Sep 17 '10 at 2:11
Indeed this seems to be the case: tex.stackexchange.com/questions/3184/… –  Caramdir Sep 17 '10 at 2:37

Edit: A general solution to apply some some styles (like put an arrow in the middle) to each segment of an arbitrary path.

There are two styles:

• the on each segment style uses the show path construction decoration of decorations.pathreplacing library to apply some styles (its argument) on each segment of a path.

• the mid arrow style uses the method of Caramdir's answer (via decorations.markings library) to put an arrow in the middle of a path (its argument is the color of the arrow).

First, the preamble:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{decorations.pathreplacing,decorations.markings}


The two styles:

\tikzset{
% style to apply some styles to each segment of a path
on each segment/.style={
decorate,
decoration={
show path construction,
moveto code={},
lineto code={
\path [#1]
(\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
},
curveto code={
\path [#1] (\tikzinputsegmentfirst)
.. controls
(\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb)
..
(\tikzinputsegmentlast);
},
closepath code={
\path [#1]
(\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
},
},
},
% style to add an arrow in the middle of a path
mid arrow/.style={postaction={decorate,decoration={
markings,
mark=at position .5 with {\arrow[#1]{stealth}}
}}},
}


Then the result and the document:

\begin{document}
\begin{tikzpicture}
\path [draw=blue,postaction={on each segment={mid arrow=red}}]
(.2,0) -- (3,1) arc (0:180:1.4 and 1) -- cycle
(4,1) circle(.8)
(6,1) ellipse(.5 and 1)
(0,3) to [bend left] (3,4)
(4,3) rectangle (6,4)
;
\end{tikzpicture}
\end{document}

-

(A modification of Caramdir's solution using Ulrich Schwarz's answer to ”Applying a postaction to every path in TikZ”.)

\makeatletter
\tikzset{nomorepostaction/.code={\let\tikz@postactions\pgfutil@empty}}
\makeatother
\begin{tikzpicture}[
every path/.style={
very thick,
postaction={nomorepostaction,decorate,
decoration={markings,mark=at position 0.5 with {\arrow{>}}}
}
}
]
\draw (-4,0)--(4,0);
\draw (4,0)--(4,2);
\draw (4,2)--(-4,2);
\draw (-4,2)--(-4,0);
\end{tikzpicture}

-

Given that the precise syntax you specify isn't possible, here's something that achieves the desired effect without having to specify the coordinates of the midpoints.

\documentclass{article}
\thispagestyle{empty}
\usepackage{tikz}
\usetikzlibrary{arrows}
\newcommand{\midarrow}{\tikz \draw[-triangle 90] (0,0) -- +(.1,0);}

\begin{document}
\begin{tikzpicture}
\begin{scope}[very thick, every node/.style={sloped,allow upside down}]
\draw (-4,0)-- node {\midarrow} (4,0);
\draw (4,0)-- node {\midarrow} (4,2);
\draw (4,2)-- node {\midarrow} (-4,2);
\draw (-4,2)-- node {\midarrow} (-4,0);
\end{scope}
\end{tikzpicture}
\end{document}


(the arrows tikz library is just to get more prominent arrowheads)

This produces:

(not sure what that vertical line is down the right-hand side. It's not in the original so must be an artefact of the pdf->png process)

-

Without decoration and with a "unique" path, a new code is :

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows}

\begin{document}
\tikzset{%
insert new path/.style={%
insert path={%
node[midway,sloped]{\tikz \draw[#1,thick] (-.2pt,0) -- ++(.2 pt,0);}
}
}
}

\begin{tikzpicture}
\begin{scope}[a/.style = {insert new path = {-triangle 90}}]
\draw[red] (-4,0) -- (4,0) -- (4,2) -- (-4,2) -- (-4,0);
\draw[red] (0,-4pt)--(0,+4pt); % it's a  test
\draw (-4,0)-- (4,0)[a] -- (4,2)[a] -- (-4,2)[a] -- (-4,0)[a];
\end{scope}
\end{tikzpicture}

\end{document}


It's possible to adjust the position of the arrows with something like node[midway,sloped,right=-2pt]

-

PSTricks equivalent (out of the box):

\documentclass[pstricks,border=12pt]{standalone}