# Pgfplot and sampling at specific points

I am trying to understand how to use the samples at option with ... from pgfplots. Consider the MWE

\documentclass{standalone}

\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\begin{document}
\begin{tikzpicture}[line/.style={black, thick},
declare function={foo(\x) =
max(0, 4 + min(0, (\x-4)^3));
},]
\begin{axis}[xmin=-1, xmax=6, axis on top]
\addplot[line, color=black, domain=-1:6]{foo(x)};
\addplot[line, color=blue, samples at={-1, 2.4125, 4, 6}]{foo(x)};
\addplot[line, color=red, samples at={-1, 2.4125,...,4, 6}]{foo(x)};
\addplot[line, color=green, samples at={-1, ...,2.4125,...,4, ...,6}]{foo(x)};
\end{axis}
\end{tikzpicture}
\end{document}


Drawing the lint without samples at produces artefacts due to the under sampling of the points in the mid region. The second addplot

\addplot[line, color=blue, samples at={-1, 2.4125, 4, 6}]{foo(x)};


Works as expected by adding the specific sampling points at the provided locations.

However, the third addplot

\addplot[line, color=red, samples at={-1, 2.4125,...,4, 6}]{foo(x)};


does not work. I expected it to add more samples in the range [2.4125,4], instead it does something weird. Finally, the last addplot

\addplot[line, color=green, samples at={-1, ...,2.4125,...,4, ...,6}]{foo(x)};


I expected to produce something similar to the plot without samples at except for additional points at 2.4125, 4 and 6. Instead the line seems to loop around!

I suspect I am misusing samples at, but I am not sure how to correct my usage.

## 1 Answer

You should specify the step to fill the list. Otherwise it is set to 1. This is from pgfmanual.

Normally, when a list item ... is encountered, there should already have been two list items before it, which where numbers. Examples of numbers are 1, -10, or -0.24. Let us call these numbers x and y and let d := y − x be their difference. Next, there should also be one number following the three dots, let us call this number z.

In this situation, the part of the list reading “x,y,...,z” is replaced by “x, x + d, x + 2d, x + 3d, ..., x + md”, where the last dots are semantic dots, not syntactic dots. The value m is the largest number such that x + md ≤ z if d is positive or such that x + md ≥ z if d is negative.

Perhaps it is best to explain this by some examples: The following have the same effects:

\foreach \x in {1,2,...,6} {\x, } yields 1, 2, 3, 4, 5, 6,

\foreach \x in {1,2,3,...,6} {\x, } yields 1, 2, 3, 4, 5, 6,

\foreach \x in {1,3,...,11} {\x, } yields 1, 3, 5, 7, 9, 11,

\foreach \x in {1,3,...,10} {\x, } yields 1, 3, 5, 7, 9,

\foreach \x in {0,0.1,...,0.5} {\x, } yields 0, 0.1, 0.20001, 0.30002, 0.40002,

\foreach \x in {a,b,9,8,...,1,2,2.125,...,2.5} {\x, } yields a, b, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 2.125, 2.25, 2.375, 2.5

As can be seen, for fractional steps that are not multiples of 2−n for some small n, rounding errors can occur pretty easily. Thus, in the second last case, 0.5 should probably be replaced by 0.501 for robustness.

There is another special case for the ... statement: If the ... is used right after the first item in the list, that is, if there is an x, but no y, the difference d obviously cannot be computed and is set to 1 if the number z following the dots is larger than x and is set to −1 if z is smaller.

So if you want samples from -1 to 2.4125 to 4 to 6, you can code

\addplot[line, color=cyan, samples at={-1,-.5,...,2.4125, 2.5,2.8,...,4, 4,4.6,...,6}]{foo(x)};


we start at -1 to 2.4125 by 0.5, then from 2.5 to 4 by 0.3 and from 4 to 6 by 0.6.

You can compare with

\addplot[line, color=black, domain=-1:6, samples=100]{foo(x)};

• Thanks! That makes sense. Is there no way to change the default step size? Feb 10, 2021 at 13:46
• I don't think we can change the default step…
– NBur
Feb 10, 2021 at 13:50