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?

2

3 Answers 3

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

4
  • Thank you, I somehow missed the shorten > option. Feb 24, 2011 at 3:58
  • 3
    The exact value is 1.8pt+1.4\pgflinewidth which is 2.92pt for a thick line.
    – Luigi
    May 20, 2013 at 17:48
  • @Luigi: Where did you get the information about the exact value? May 21, 2013 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, 2013 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}
4
  • I think it's not as simple as you imagine.
    – Luigi
    May 20, 2013 at 18:24
  • Ok. I'm sorry. The left extend is correct, but the right extend should simply be 4.5\pgfutil@tempdima if you want the center of the circle at the end of the line (IMHO).
    – Luigi
    May 20, 2013 at 18:34
  • @Luigi: Yes, that seems right. Edited, thank you!
    – Jake
    May 20, 2013 at 18:40
  • 3
    Thanks, this is great! I packaged it and placed it on github: github.com/lahvak/intervalarrows Oct 9, 2015 at 2:25
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

You must log in to answer this question.

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