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

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}

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:

enter image description here

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

Update: 2020-02-22: This code has been superseded and shouldn't be used. It also nests tikzpictures, something that I later realised was Not Good. Caramdir's answer is the best all-round solution, but if you want something that is close to this one then Kpym's answer using pics has the same spirit as this but without the drawbacks.


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:

alt text

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