# Linear regression with dates on x axis in pgfplots

As in this question, I need to add a linear regression line to a plot which has dates on the x axis, but I get following error: ! Package PGF Math Error: Could not parse input '2017-01-01' as a floating point number, sorry.

Unfortunately, the dates are not all consecutive as in the linked question, so I cannot use the proposed answer, that is using x expr=\coordindex.

How could I do?

\documentclass{standalone}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.14}
\usepgfplotslibrary{dateplot}
\usepackage{filecontents}

\begin{filecontents}{testtable.csv}
date;value
2017-01-01;0
2017-01-02;1
2017-01-11;2
2017-01-12;3
2017-02-01;4
2017-02-02;5
\end{filecontents}

\begin{document}
\begin{tikzpicture}
\begin{axis} [date coordinates in=x]
\addplot+ table [y={create col/linear regression={y=value}}] {\testtable};
\end{axis}
\end{tikzpicture}
\end{document}

• \pgfcalendardatetojulian will convert the date into a number. See page 906 of PGF manual. Apr 29 '17 at 14:22
• Intrernally pgfplots uses % #1 the date % #2 the hours % #3 the minutes % #4 is either empty or is the seconds. % #5 a macro which will be filled with the date part. % #6 the macro which will contain a number in the range [0,1] % representing hours and minutes. % % If you don't have seconds, you have to provide the second ':' sign % as dummy! In that case #4 will be empty. \def\pgfplotslibdateplot@map@time#1 #2:#3:#4\dateto#5\timeto#6{% Apr 29 '17 at 14:38
• @JohnKormylo I know about \pgfcalendardatetojulian. The question is: how to use this macro inside the \addplot command? Could you set up an mwe, please? Apr 29 '17 at 18:24
• You can use it to create a new column using pgfplotstable. Apr 30 '17 at 2:21

As was already suggested by John Kormylo in the comments below the question, the key is to convert the dates to integers in a new column of the data table.

For more details, please have a look at the comments in the code.

% used PGFPlots(Table) v1.14
% (borrowed code from <https://tex.stackexchange.com/a/302298/95441>)
\begin{filecontents*}{testtable.csv}
date;value
2017-01-01;0
2017-01-02;1
2017-01-11;2
2017-01-12;3
2017-02-01;4
2017-02-02;5
\end{filecontents*}
\documentclass[border=5pt]{standalone}
\usepackage{tikz}
\usepackage{pgfcalendar}    % <-- to convert the dates to Julian integers
\usepackage{pgfplots}
\usepackage{pgfplotstable}  % <-- to manipulate the data file/table
\usepgfplotslibrary{dateplot}
\pgfplotsset{compat=1.14}
% add new column with Julian integer numbers
% therefore a counter is needed
\newcount\julianday
\pgfplotstablecreatecol[
create col/assign/.code={
% convert the number of the current row and save it to \julianday'
\pgfcalendardatetojulian{\thisrow{date}}{\julianday}
% then give the entry of \julianday' to \entry' which is then
% given to the current cell
\edef\entry{\the\julianday}
\pgfkeyslet{/pgfplots/table/create col/next content}\entry
},
]{JulianDay}{\data}
% because the dateplot' library shifts automatically all dates to 0 using
% the first found coordinate we can't use the created JulianDay' data
% directly for linear regression', but have to do the same first with
% the data
% get the first coordinate of the column ...
\pgfplotstablegetelem{0}{JulianDay}\of{\data}
% ... and store it in \xmin'
\pgfmathtruncatemacro{\xmin}{\pgfplotsretval}
% now create another column with the shifted values
\pgfplotstablecreatecol[
expr={\thisrow{JulianDay}-\xmin},
]{JulianDayMod}{\data}
\begin{document}
% --------------------------------------------------------
%% for debugging purposes only
%% show resulting numbers, if you want
%\pgfplotstabletypeset[
%    column type=l,
%    columns={date,JulianDay,JulianDayMod,value},
%    columns/date/.style={string type},
%    columns/JulianDay/.style={/pgf/number format/fixed},
%]\data
% --------------------------------------------------------
\begin{tikzpicture}
\begin{axis}[date coordinates in=x]
\addplot+ [only marks] table [x=date,y=value] {\data};
`