# tikz: How to place an arrow with label exactly in the middle of a line?

In the following example, the label is in the middle of the line. But the arrow, which acts as a marker, is not in the middle. Only its head but not the center of the arrow.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows,decorations.markings}

\begin{document}
\begin{tikzpicture}[
middlearrow/.style 2 args={
decoration={
markings,
mark=at position 0.5 with {\arrow{triangle 45}, \node[#1] {#2};}
},
postaction={decorate}
}
]
\draw[middlearrow={below}{+}]        (0,0) -- (1,0);
\end{tikzpicture}
\end{document}


-

As noticed, the markings mechanism puts the arrow in the selected position taking as reference its arrowhead. The following example demonstrates it clearly:

\documentclass[tikz,border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows,decorations.markings,plotmarks}

\begin{document}
\begin{tikzpicture}[
middlearrow/.style 2 args={
decoration={
markings,
mark=at position 0.5 with {\arrow{triangle 45}, \node[#1] {#2};}
},
postaction={decorate}
},
my mark/.style={
decoration={
markings,
mark=at position 0.5 with{\color{red}\pgfuseplotmark{x}},
},
postaction=decorate,
}
]
\draw[middlearrow={below}{+},my mark]        (0,0) -- (1,0);
\draw[middlearrow={below}{+},my mark]        (0,-1) -- (2,-1);
\draw[middlearrow={below}{+},my mark]        (0,-2) -- (4,-2);
\end{tikzpicture}
\end{document}


What to do then? Steven showed one possibility. The same approach can be taken, easily, using only TikZ options, specifically xshift:

\documentclass[tikz,border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows,decorations.markings,plotmarks}

\begin{document}
\begin{tikzpicture}[
middlearrow/.style 2 args={
decoration={
markings,
mark=at position 0.5 with {\arrow[xshift=3.333pt]{triangle 45}, \node[#1] {#2};}
},
postaction={decorate}
},
]
\draw[middlearrow={below}{+}]        (0,0) -- (1,0);
\draw[middlearrow={below}{+}]        (0,-1) -- (2,-1);
\draw[middlearrow={below}{+}]        (0,-2) -- (4,-2);
\end{tikzpicture}
\end{document}


The "magic number" seems to be correct. To be really precise, one should go in pgflibraryarrows.code.tex file and compute the exact width of triangle 45 arrow.

This solution does not prevent errors while changing line width.

-
Thanks. It works with this "magic number". I'm wondering, if it could be "calculated" or "found out" automatically from the file pgflibraryarrows.code.tex you mentioned in such a way that also other arrow styles can be used. (Like: center_point_of_arrow_head = (arrow_head_right - arrow_head_left)/2. And then calculating new xshift value.) –  leacbern May 6 '14 at 9:24
@leacbern: you're welcome :) Telling truth, I don't think you can have one for all xshift; perhaps with the new arrows.meta library things are different. You can always post a new question for such a problem: here we have some tikz-arrows experts :) –  Claudio Fiandrino May 6 '14 at 9:40

Both the arrow and the plus sign were shifted \makeboxes, and seem to work over various length spans. I'm guessing, however, that the actual size of the makeboxes will depend on the size of the arrow head.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{arrows,decorations.markings}
\begin{document}
\begin{tikzpicture}[
middlearrow/.style 2 args={
decoration={
markings,
mark=at position 0.5 with {%
\makebox[4pt][r]{\arrow{triangle 45}}, \node[#1] {#2};}
},
postaction={decorate}
}
]
\draw[middlearrow={below}{\makebox[1pt][r]{+}}]        (0,0) -- (1,0);

\draw[middlearrow={below}{\makebox[1pt][r]{+}}]        (0,-.5) -- (2,-.5);

\draw[middlearrow={below}{\makebox[1pt][r]{+}}]        (0,-1) -- (3,-1);

\end{tikzpicture}
\end{document}


-
thanks for the hint with the \makebox command. But unfortunately you have to change the position value for different line lengths. –  leacbern May 5 '14 at 13:58
@leacbern Please see revision. –  Steven B. Segletes May 5 '14 at 14:13