7

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}

enter image description here

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.

2 Answers 2

11

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%
  \advance\pgfutil@tempdima by1.5\pgflinewidth%
  \pgfutil@tempdimb=\pgfutil@tempdima%
  \advance\pgfutil@tempdimb by\pgflinewidth%
  \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}
5
  • 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, 2012 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, 2012 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, 2012 at 19:29
  • @Jake, I agree that it depends on what one wants. I would like the bracket out of the line.
    – Luigi
    Nov 13, 2012 at 19:33
  • 1
    @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, 2012 at 8:28
5

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}

enter image description here

1
  • Thanks, it works but it seems a bit like a manual adjustment to me..
    – Corentin
    Nov 13, 2012 at 23:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .