Alignment of labels in piecewise linear Tikz plot

I have the following code to draw a piecewise linear function and label it.

\begin{tikzpicture}[
declare function={
func(\x)= (\x<=4) * (50)   +
and (\x>=4, \x<7) * (49.999 - 2*(\x-4))     +
and (\x>=7,  \x<=10) * (42-10*(\x-7)) ;
}
]    \begin{axis}[ticks=none,
axis x line=middle, axis y line=middle,
ymin=20, ymax=60, ytick={}, ylabel=$x_D(t)$,
xmin=0, xmax=12, xtick={}, xlabel=$t$,
]
\filldraw (38,380) circle (1pt) node [right,font=\tiny] {$(t_B, x_D$)};
\filldraw (67,325) circle (1pt) node [right,font=\tiny] {$(t_C, x_D^\prime$)};
\filldraw (92,83) circle (1pt) node [right,font=\tiny] {$(t_D, 0$)};

\end{axis}
\end{tikzpicture}


I have three problems:

1. Instead of three nice piecewise linear segments, I get a slight tilt between the first two lines.

2. The filldraw coordinates are extremely difficult to find, I have to use trial and error - is there any way to directly map them to the actual axis coordinates?

3. The last label $(t_D,0)$ goes inside and it is barely visible.

• Why don't you let pgfplots place the markers? – percusse Mar 16 '16 at 14:00
• @percusse: How to do that? – Bravo Mar 16 '16 at 14:09

First of all, whe plotting piecewise functions, you have to plot the function twice at corner points since two different formulas are used. For example you plotted at x=4,5. The plot should have been plotted at x=3.99,4.01 (or twice at 4 with the different formulas). So I modified the code to manually place the samples using samples at option.

Also in this code, if the sample lies exactly on 4, both formulas get executed. You should probably change one of the inequality to strict inequality (like you have done with 7).

Also there was some continuity issue in your formulas them selves (unless that was intentional). I have corrected that also. Always evaluate and see at the corner points if the left formula and right formula match in value (if you want piecewise continuous functions).

To place labels at corners, I used the axis coordinate system using axis cs. This option uses the axes to define the coordinates rather than the default tikz coordinates.

Note that the last label disappearing problem is currently fixed by changing ymin option. There may be better way.

\documentclass[]{article}
\usepackage{pgfplots}
\begin{document}

\begin{tikzpicture}[
declare function={
func(\x)= (\x<=4) * (50)   +
and (\x>=4, \x<7) * (50 - 2*(\x-4))     +
and (\x>=7,  \x<=10) * (44-10*(\x-7)) ;
}
]    \begin{axis}[ticks=none,
axis x line=middle, axis y line=middle,
ymin=14, ymax=60, ytick={}, ylabel=$x_D(t)$,
xmin=0, xmax=12, xtick={}, xlabel=$t$,
]
4.01, 6.99, 7.01, 10}
]{func(x)};
\filldraw (axis cs: 4,50) circle (1pt) node [right,font=\tiny] {$(t_B, x_D$)};
\filldraw (axis cs: 7,44) circle (1pt) node [right,font=\tiny] {$(t_C, x_D^\prime$)};
\filldraw (axis cs: 10,14) circle (1pt) node
[above, anchor=south west, font=\tiny] {$(t_D, 0$)};

\end{axis}
\end{tikzpicture}

\end{document}


• Thanks, how do I get the axis to be adjoint to the line? I want no space between the curve and the axes. – Bravo Mar 16 '16 at 14:24
• see the edit on ymin and anchor = south west – AJN Mar 16 '16 at 14:27
• May be someone will show and example of automatic label placement. I don't have much experience with pgfplots. – AJN Mar 16 '16 at 14:30