1

I have a pgfplot with dates for x and some values for y, for which I now want to add a mean line like it is done here. The function \DrawHMean presented there however seems to have a problem with dates, I suspect \pgfkeysvalueof{/pgfplots/xmin} and …xmax}. Unfortunately, a simple \addplot expression {y=\Mean} doesn't work as well. What can I do to get the (already calculated!) mean into the graph?

MWE

The commented line responsible for drawing the mean line yields date related errors when activated.

\documentclass[varwidth=100cm,border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{dateplot}
\pgfplotsset{compat=1.9}

\usepackage{filecontents}
\begin{filecontents*}{data.csv}
value date
1.84919 2017-04-09
0.97280 2017-04-10
4.78586 2017-04-11
3.95797 2017-04-12
4.50753 2017-04-13
2.52274 2017-04-14
5.13984 2017-04-15
0.29474 2017-04-16
5.39946 2017-04-17
4.40204 2017-04-18
\end{filecontents*}

\newcommand\DrawHMean[1][]{
\draw[#1]
  (axis cs:\pgfkeysvalueof{/pgfplots/xmin},\Mean) --
  (axis cs:\pgfkeysvalueof{/pgfplots/xmax},\Mean);
}

\newcommand\GetMean[2]{
  \pgfplotstableread{#1}\tableA
  \pgfplotstableset{
create on use/new/.style={
create col/expr={\pgfmathaccuma + \thisrow{#2}}},
  }
  \pgfplotstablegetrowsof{\tableA}
  \pgfmathsetmacro{\NumRows}{\pgfplotsretval}
  \pgfplotstablegetelem{\numexpr\NumRows-1\relax}{new}\of{#1}
  \pgfmathsetmacro{\Sum}{\pgfplotsretval}
  \pgfmathsetmacro{\Mean}{\Sum/\NumRows}
}

\begin{document}
\begin{tikzpicture}
  \GetMean{data.csv}{value}
  \begin{axis}[%
    date coordinates in=x,%
    xticklabel style={rotate=90,anchor=near xticklabel},%
    xticklabel=\day.\month.\year,%
  ]
    \addplot[red] table [x=date, y=value] {data.csv};
%     \DrawHMean[blue, ultra thick, dashed]
  \end{axis}
\end{tikzpicture}
\end{document}

Output

http://imgur.com/w4PREX1

Thanks for helping!

4

You can search the first date given in the table

\newcommand\FirstDate{}
\newcommand\GetFirstDate[2]{%
  \pgfplotstablegetelem{0}{#2}\of{#1}%
  \edef\FirstDate{\pgfplotsretval}%
}

and use it in

\newcommand\DrawHMean[2][]{%
  \draw[#1]
    ({axis cs:\FirstDate,\Mean}-|current axis.west) -- 
    ({axis cs:\FirstDate,\Mean}-|current axis.east);%
}

enter image description here

Code:

\documentclass[varwidth=100cm,border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{dateplot}
\pgfplotsset{compat=1.9}

\usepackage{filecontents}
\begin{filecontents*}{data.csv}
value date
1.84919 2017-04-09
0.97280 2017-04-10
4.78586 2017-04-11
3.95797 2017-04-12
4.50753 2017-04-13
2.52274 2017-04-14
5.13984 2017-04-15
0.29474 2017-04-16
5.39946 2017-04-17
4.40204 2017-04-18
\end{filecontents*}

\newcommand\DrawHMean[2][]{%
  \draw[#1]
    ({axis cs:\FirstDate,\Mean}-|current axis.west) -- 
    ({axis cs:\FirstDate,\Mean}-|current axis.east);%
}
\newcommand\FirstDate{}
\newcommand\GetFirstDate[2]{%
  \pgfplotstablegetelem{0}{#2}\of{#1}%
  \edef\FirstDate{\pgfplotsretval}%
}
\newcommand\GetMean[2]{
  \pgfplotstableread{#1}\tableA
  \pgfplotstableset{
    create on use/new/.style={
    create col/expr={\pgfmathaccuma + \thisrow{#2}}},
  }
  \pgfplotstablegetrowsof{\tableA}
  \pgfmathsetmacro{\NumRows}{\pgfplotsretval}
  \pgfplotstablegetelem{\numexpr\NumRows-1\relax}{new}\of{#1}
  \pgfmathsetmacro{\Sum}{\pgfplotsretval}
  \pgfmathsetmacro{\Mean}{\Sum/\NumRows}
}

\begin{document}
\begin{tikzpicture}
  \GetFirstDate{data.csv}{date}
  \GetMean{data.csv}{value}
  \begin{axis}[clip=false,%
    date coordinates in=x,%
    xticklabel style={rotate=90,anchor=near xticklabel},%
    xticklabel=\day.\month.\year,%
  ]
    \addplot[red] table [x=date, y=value] {data.csv};

     \DrawHMean[blue, ultra thick, dashed]{data.csv}
  \end{axis}
\end{tikzpicture}
\end{document}
0
0

I came across a simpler solution using an internal function, in the axis options I added:

extra y ticks=\Mean,
extra y tick style={thick,blue,grid=major,grid style={thick,blue,dashed}},
extra y tick label={mean = $\pgfmathprintnumber\tick$},

This sets \Mean (which of course still needs to be calculated by \GetMean before) as an extra tick on the y axis. The whole example looks as follows:

\documentclass[varwidth=100cm,border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepgfplotslibrary{dateplot}
\pgfplotsset{compat=1.9}

\usepackage{filecontents}
\begin{filecontents*}{data.csv}
value date
1.84919 2017-04-09
0.97280 2017-04-10
4.78586 2017-04-11
3.95797 2017-04-12
4.50753 2017-04-13
2.52274 2017-04-14
5.13984 2017-04-15
0.29474 2017-04-16
5.39946 2017-04-17
4.40204 2017-04-18
\end{filecontents*}

\newcommand\GetMean[2]{
  \pgfplotstableread{#1}\tableA
  \pgfplotstableset{
create on use/new/.style={
create col/expr={\pgfmathaccuma + \thisrow{#2}}},
  }
  \pgfplotstablegetrowsof{\tableA}
  \pgfmathsetmacro{\NumRows}{\pgfplotsretval}
  \pgfplotstablegetelem{\numexpr\NumRows-1\relax}{new}\of{#1}
  \pgfmathsetmacro{\Sum}{\pgfplotsretval}
  \pgfmathsetmacro{\Mean}{\Sum/\NumRows}
}

\begin{document}
\begin{tikzpicture}
  \GetMean{data.csv}{value}
  \begin{axis}[%
date coordinates in=x,%
xticklabel style={rotate=90,anchor=near xticklabel},%
xticklabel=\day.\month.\year,%
extra y ticks=\Mean,
extra y tick style={thick,blue,grid=major,grid style={thick,blue,dashed}},% style options
extra y tick label={mean = $\pgfmathprintnumber\tick$},% label text, change to {} for empty label
  ]
\addplot[red] table [x=date, y=value] {data.csv};
  \end{axis}
\end{tikzpicture}
\end{document}

Output

I leave esdd's answer as the accepted one since it answers my exact question, however this approach in my opinion serves better as a solution to the overall problem how to add a automatically calculated mean line to a pgfplot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.