# TikZ: Precisely controlling arrow tip position

Usually, when drawing a path with an arrow tip in TikZ, we want the tip to end precisely at the last point of the path, and this is what TikZ does by default. However, with some specific arrow tips, one may wish to control a little more precisely the position of the arrow tip: for instance you may want the base of the arrow to be positioned at the last point of the past instead of the tip.

Here is an example drawing an interval on the real line:

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

\begin{document}
\begin{tikzpicture}
\draw (-3,0) -- (3,0) node[anchor=south] {$\mathbb{R}$};
\foreach \x in {-1,0,1} \draw (\x,2pt) -- (\x, -2pt) node[anchor=north] {$\x$};
\draw[thick,blue,[-[] (-1,0) -- (1,0);
\end{tikzpicture}
\end{document}


Is it possible to make sure that the closing square bracket [ is positioned on the tick corresponding to x=1? Of course, it is possible to adjust it manually but this does not seem to be a satisfactory solution.

-

I would declare a new arrow tip based on the old one but setting \pgfarrowsleftextend to 0pt.

The syntax for defining arrow tips is explained in section 74 "Arrow Tips" of the PGF manual.

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

\makeatletter
\pgfarrowsdeclare{[*}{]*}
{
\pgfarrowsleftextend{0pt}
\pgfarrowsrightextend{0pt}
}
{
\pgfutil@tempdima=2pt%
\pgfutil@tempdimb=\pgfutil@tempdima%
\pgfsetdash{}{+0pt}
\pgfsetmiterjoin
\pgfsetbuttcap
\pgfpathmoveto{\pgfqpoint{-.5\pgfutil@tempdimb}{-1\pgfutil@tempdima}}
\pgfpathlineto{\pgfqpoint{0pt}{-1\pgfutil@tempdima}}
\pgfpathlineto{\pgfqpoint{0pt}{\pgfutil@tempdima}}
\pgfpathlineto{\pgfqpoint{-.5\pgfutil@tempdimb}{\pgfutil@tempdima}}
\pgfusepathqstroke
}

\pgfarrowsdeclarereversed{]*}{[*}{[*}{]*}
\makeatother

\begin{document}
\begin{tikzpicture}
\draw (-3,0) -- (3,0) node[anchor=south] {$\mathbb{R}$};
\foreach \x in {-1,0,1} \draw (\x,2pt) -- (\x, -2pt) node[anchor=north] {$\x$};
\draw[thick,blue,[*-[*] (-1,0) -- (1,0);
\end{tikzpicture}
\end{document}


For use in a plot (either using PGFPlots or the \draw plot command), you might want a plot mark instead of an arrow tip:

\documentclass{standalone}
\usepackage{pgfplots}

\makeatletter
\pgfdeclareplotmark{]}
{%
\pgfpathmoveto{\pgfqpoint{-0.65\pgfplotmarksize}{\pgfplotmarksize}}
\pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}
\pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}
\pgfpathlineto{\pgfqpoint{-0.65\pgfplotmarksize}{-\pgfplotmarksize}}
\pgfusepathqstroke
}

\pgfdeclareplotmark{[}
{%
\pgfpathmoveto{\pgfqpoint{0.65\pgfplotmarksize}{\pgfplotmarksize}}
\pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}
\pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}
\pgfpathlineto{\pgfqpoint{0.65\pgfplotmarksize}{-\pgfplotmarksize}}
\pgfusepathqstroke
}
\makeatother

\begin{document}
\begin{tikzpicture}
\begin{axis}[
yshift=4cm,
y = 1cm,
xmin = -2, xmax = 2,
ymin = -1, ymax = 1,
hide y axis,
axis x line* = middle,
disabledatascaling
]
\addplot [thick, blue, mark={[}, mark size=1mm] coordinates {(-1,0) (1,0)};
\end{axis}
\end{tikzpicture}
\end{document}

-
@cmhughes: Thanks, done! –  Jake Nov 13 '12 at 16:22
This is not useful in PGFPlots, could you give the code to use this with PGFPlots? Anyway, this is a great tip! –  Manuel Nov 13 '12 at 17:10
@Jake, to be more precise, \pgfarrowsleftextend{+0.5\pgflinewidth} would be better if you have a large line width, otherwise the line could be shortened by half the line thickness (but in this case I think it's all right). –  Luigi Nov 13 '12 at 19:20
@Luigi: Even if you set line width=4pt for the arrow and draw the thin tick marks on top of the arrow, the vertical arrow line is exactly centered with respect to the tick mark. I guess which approach to take depends on whether you want the tick mark to be aligned with the center or one of the edges of the vertical line. –  Jake Nov 13 '12 at 19:29
@Manuel: You can use arrow tips in PGFPlots, but for some applications using a plot mark might make more sense. I've edited my answer. –  Jake Nov 14 '12 at 8:28

You can use shorten.:

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

\begin{document}
\begin{tikzpicture}
\draw (-3,0) -- (3,0) node[anchor=south] {$\mathbb{R}$};
\foreach \x in {-1,0,1} \draw (\x,2pt) -- (\x, -2pt) node[anchor=north] {$\x$};
\draw[thick,blue,[-[,shorten >=-2pt] (-1,0) -- (1,0);
\end{tikzpicture}
\end{document}


-
Thanks, it works but it seems a bit like a manual adjustment to me.. –  Corentin Nov 13 '12 at 23:09