Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.

share|improve this question
add comment

2 Answers

up vote 12 down vote accepted

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}
share|improve this answer
    
@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
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 '12 at 8:28
show 3 more comments

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

share|improve this answer
    
Thanks, it works but it seems a bit like a manual adjustment to me.. –  Corentin Nov 13 '12 at 23:09
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.