11

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}

Example: Label in the middle. But arrow isn't.

Pouya
  • 7,269
leacbern
  • 165

2 Answers2

6

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}

enter image description here

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}

enter image description here

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.

  • 1
    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 06 '14 at 09: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 06 '14 at 09:40
2

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}

enter image description here