# 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) – Loop Space 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
• @Sigur: I suppose changing \arrow{>} to \arrow{latex} should work. – Caramdir Sep 5 '14 at 3:39

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}

• This is really useful. I wonder if this is included in the latest version of Tikz. – berkus Jun 27 '17 at 13:01
• @BarisErkus The show path construction decoration is already included in the current version of TikZ. My on each segment style is just a simple application of this decoration. – Paul Gaborit Jun 27 '17 at 13:22
• @PaulGaborit I wanted to modify this for other arrowheads, e.g. double arrow, but it did not work. What I did was to replace "{\tikz \draw[-triangle 90] (0,0) -- +(.1,0);}" by "{\tikz \draw[-triangle 90] (0,0) -- +(.1,0); \draw[-triangle 90] (0,0)--+(.145,0);}", but this head no effect – klirk Jan 31 at 15:47
• @klirk You can use the arrows.meta library (a TikZ library) and, in my code, replace stealth by Stealth[]Stealth[] or Triangle[]Triangle[]. – Paul Gaborit Jan 31 at 20:28

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)

(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}


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}

\begin{document}

\begin{pspicture}[showgrid=bottom](4,4)
\pspolygon[ArrowInside=->,linecolor=red](0,0)(4,0)(4,4)(0,4)
\end{pspicture}

\end{document}

• The original asked for a TikZ solution, not a pstricks one. – James C. Nov 15 '12 at 1:02

I accidentally discovered this, using circuitikz:

\draw (0,0) to node[currarrow] {} (1,0);


could not yet find an alternative for currarrow in TikZ, and it doesn't work with the basic TikZ arrows. But you can do everything in circuitikz what you can in TikZ, and more!

• i forgot, the environment is: \begin{circuitikz} % code \end{circuitikz} – matekatona May 14 '15 at 14:00
• you mean alternatives except the top three answers above? – percusse May 14 '15 at 14:09
• no, I mean I did not find an alternative to the currarrow node in the basic TikZ nodes. So you have to use the circuitikz package with this solution. – matekatona Jul 27 '15 at 12:07
• btw: circuitikz also works with the basic tikzpicture environment. I personally recommend to always use the tikzpicture environment to make it easier to parse for tikzpictures in latex-code – tc88 Dec 19 '17 at 10:55

This is revisited version of Loop Space's answer using pic in place of node that were not available in 2010.

The main advantages is that the pic inherits the path style (line width, color, ...) from the current path.

\documentclass[tikz,border=7pt]{standalone}
\usetikzlibrary{arrows}
\tikzset{
arrow/.pic={\path[tips,every arrow/.try,->,>=#1] (0,0) -- +(.1pt,0);},
pics/arrow/.default={triangle 90}
}

\begin{document}
\begin{tikzpicture}
\begin{scope}[very thick,nodes={sloped,allow upside down}]
\draw (-4,0) -- pic{arrow} (4,0);
\draw (4,0) -- pic[blue]{arrow} (4,2);
\draw[thin,purple] (4,2) -- pic{arrow=latex} (-4,2);
\draw[every arrow/.style=red] (-4,2) -- pic[pos=.3]{arrow} pic[pos=.7]{arrow} (-4,0);
\end{scope}
\end{tikzpicture}
\end{document}


And you can draw your own arrow using pics, for example by redefining arrow style

arrow/.pic={\fill[every arrow/.try,scale={\pgflinewidth/1cm}]
(0,0) -- (-150:7) -- (150:7) -- (0,0) circle(2);}


will produce the following picture