26

I would like to use tikz * and o arrows to indicate included/excluded endpoints in plots of piecewise functions, like for example the following one:

Sample plot

However, it seems that tikz always aligns the "tip" of the arrow with the end of the line, so that the code

\documentclass{article} 
\usepackage{tikz}
\usetikzlibrary{arrows}
\begin{document}
\begin{tikzpicture}
   \draw[help lines] (-.1,-.1) grid (2.1,2.1);
   \draw[thick,-*] (0,1.5) -- (1,.5);
   \draw[thick,o-] (1,1.5) -- (2,.5);
\end{tikzpicture}
\end{document}

produces

tikz arrows (incorrect alignment)

where I would like the circles to be vertically aligned on the grid line.

Is there a parameter or code I can modify to get the desired behavior?

Jan Hlavacek
  • 19,242

3 Answers3

19

There are the shorten < and shorten > option which allow you to shorten the arrow length from the start and end of the line, respectively. It also accepts negative values which then extend the arrow head forwards:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{arrows}
\begin{document}
\begin{tikzpicture}[shorten >=-3pt,shorten <=-3pt]
   \draw[help lines] (-.1,-.1) grid[step=.5] (2.1,2.1);
   \draw[thick,-*] (0,1.5) -- (1,.5);
   \draw[thick,o-] (1,1.5) -- (2,.5);
\end{tikzpicture}
\end{document}

The 3pt was just a lucky guess, but seems to be the correct value for this arrow heads.

Result:

Result

gerrit
  • 5,165
Martin Scharrer
  • 262,582
  • Thank you, I somehow missed the shorten > option. – Jan Hlavacek Feb 24 '11 at 03:58
  • 3
    The exact value is 1.8pt+1.4\pgflinewidth which is 2.92pt for a thick line. – Luigi May 20 '13 at 17:48
  • @Luigi: Where did you get the information about the exact value? – Dr. Manuel Kuehner May 21 '13 at 12:32
  • 1
    @ManuelKuehner from the code of the arrowhead. The radius of the circle line included is 4.5\pgfutil@tempdima + 0.5\pgflinewidth (see Jake's answer for the code), hence you have to move the center by this quantity taking into account that thick means line width=0.8pt. – Luigi May 21 '13 at 17:51
15

If you want to avoid having to guess the value for the shorten < key, you can define new arrow heads that will place the circles precisely at the specified coordinate:

\documentclass[]{standalone}

\usepackage{tikz}
\usepackage{pgfplots}
\usepgflibrary{arrows}

\makeatletter
\pgfarrowsdeclare{center*}{center*}
{
  \pgfarrowsleftextend{+-.5\pgflinewidth}
  \pgfutil@tempdima=0.4pt%
  \advance\pgfutil@tempdima by.2\pgflinewidth%
  \pgfarrowsrightextend{4.5\pgfutil@tempdima}
}
{
  \pgfutil@tempdima=0.4pt%
  \advance\pgfutil@tempdima by.2\pgflinewidth%
  \pgfsetdash{}{+0pt}
  \pgfpathcircle{\pgfqpoint{4.5\pgfutil@tempdima}{0bp}}{4.5\pgfutil@tempdima}
  \pgfusepathqfillstroke
}

\pgfarrowsdeclare{centero}{centero}
{
  \pgfarrowsleftextend{+-.5\pgflinewidth}
  \pgfutil@tempdima=0.4pt%
  \advance\pgfutil@tempdima by.2\pgflinewidth%
  \pgfarrowsrightextend{4.5\pgfutil@tempdima}
}
{
  \pgfutil@tempdima=0.4pt%
  \advance\pgfutil@tempdima by.2\pgflinewidth%
  \pgfsetdash{}{+0pt}
  \pgfpathcircle{\pgfqpoint{4.5\pgfutil@tempdima}{0bp}}{4.5\pgfutil@tempdima}
  \pgfusepathqstroke
}
\makeatother

\begin{document}
\begin{tikzpicture}
   \draw[help lines] (-.1,-.1) grid (2.1,2.1);
   \draw[thick,-center*] (0,1.5) -- (1,.5);
   \draw[thin,centero-] (1,1.5) -- (2,.5);
\end{tikzpicture}
\end{document}
Luigi
  • 6,325
Jake
  • 232,450
2

With the newer arrows.meta library, this can be achieved by setting the sep to the negative of half the arrow tip's length. Since the default value for the length of the Circle arrow tip is

length  = +2.39365pt +3.191538

we'll be using

Circle[sep=-1.196825pt -1.595769]

Code

\documentclass[tikz]{standalone}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{tikzpicture}[
  */.tip={Circle[sep=-1.196825pt -1.595769]},
  o/.tip={Circle[sep=-1.196825pt -1.595769, open]},
]
   \draw[help lines] (-.1,-.1) grid (2.1,2.1);
   \draw[thick, -*] (0,1.5) -- (1,.5);
   \draw[thick, o-] (1,1.5) -- (2,.5);
\end{tikzpicture}
\end{document}

Output

enter image description here

Qrrbrbirlbel
  • 119,821