2

I have the following MWE where I want to place the data from file myintervals.csv as filled area behind my bar plot. There is a problem with expandable macro here, but I don't get it working correctly:

\documentclass[tikz]{standalone}
\usepackage{luatex85}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{pgfcalendar}
\usepackage{filecontents}
\usepgfplotslibrary{dateplot}

\begin{filecontents*}{mydata.csv}
monthlyTimeString;numberOfBypassTrips;numberOfBatteryTrips;numberOfMainsTrips
2016-11-30;12;0;3
2016-12-31;0;0;0
2017-01-31;0;3;0
2017-02-28;0;0;0
2017-03-31;0;4;0
2017-04-30;0;3;5
2017-05-31;8;0;0
2017-06-30;0;4;0
\end{filecontents*}

\begin{filecontents*}{myintervals.csv}
type,startDate,stopDate
commissioning,2016-11-15,2017-01-15
service,2017-05-15,2017-07-15
\end{filecontents*}

\begin{document}
\pgfplotstableread[col sep=semicolon,string type]{mydata.csv}\data
\pgfplotstableread[col sep=comma,string type]{myintervals.csv}\intervals
\begin{tikzpicture}
\begin{axis}[
  ymin=0,
  date coordinates in=x,
  xticklabel={\month/\year},
  ybar stacked,
  x tick label style={rotate=90,anchor=east},
  xlabel=Date,
  xlabel near ticks,
  ylabel=Number of occurences,
  bar width=10pt,
  xtick=data,
  before end axis/.code={
    \pgfplotstablegetrowsof{\intervals}
    \pgfmathsetmacro{\rows}{\pgfplotsretval-1}
    \pgfplotsforeachungrouped \row in {0,...,\rows}{
      \pgfplotstablegetelem{\row}{type}\of\intervals
      \edef\type{\pgfplotsretval}
      \pgfplotstablegetelem{\row}{startDate}\of\intervals
      \edef\startdate{\pgfplotsretval}
      \pgfplotstablegetelem{\row}{stopDate}\of\intervals
      \edef\stopdate{\pgfplotsretval}
      \node[gray,anchor=north west,font={\footnotesize}] at ({axis cs:\startdate,0}|-{rel axis cs:0,1}) {\type};
      \fill[opacity=0.5,gray!50] ({axis cs:\startdate,0}|-{rel axis cs:0,0}) rectangle ({axis cs:\stopdate,0}|-{rel axis cs:0,1});
    } 
  }, 
] 
  \addplot table[x=monthlyTimeString,y=numberOfBypassTrips]{\data};
  \addplot table[x=monthlyTimeString,y=numberOfBatteryTrips]{\data};
  \addplot table[x=monthlyTimeString,y=numberOfMainsTrips]{\data};
\end{axis}
\end{tikzpicture}
\end{document}

The output looks like this:

enter image description here

When it should look like this:

enter image description here

1 Answer 1

3

As you say, it's an expansion issue.

\documentclass[tikz]{standalone}
\usepackage{luatex85}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{pgfcalendar}
\usepackage{filecontents}
\usepgfplotslibrary{dateplot}

\begin{filecontents*}{mydata.csv}
monthlyTimeString;numberOfBypassTrips;numberOfBatteryTrips;numberOfMainsTrips
2016-11-30;12;0;3
2016-12-31;0;0;0
2017-01-31;0;3;0
2017-02-28;0;0;0
2017-03-31;0;4;0
2017-04-30;0;3;5
2017-05-31;8;0;0
2017-06-30;0;4;0
\end{filecontents*}

\begin{filecontents*}{myintervals.csv}
type,startDate,stopDate
commissioning,2016-11-01,2017-01-01
service,2017-05-01,2017-06-31
\end{filecontents*}

\begin{document}
\pgfplotstableread[col sep=semicolon,string type]{mydata.csv}\data
\pgfplotstableread[col sep=comma,string type]{myintervals.csv}\intervals
\begin{tikzpicture}
\begin{axis}[
  ymin=0,
  date coordinates in=x,
  xticklabel={\month/\year},
  ybar stacked,
  x tick label style={rotate=90,anchor=east},
  xlabel=Date,
  xlabel near ticks,
  ylabel=Number of occurences,
  bar width=10pt,
  xtick=data,
  before end axis/.code={
    \pgfplotstablegetrowsof{\intervals}
    \pgfmathsetmacro{\rows}{\pgfplotsretval-1}
    \pgfplotsforeachungrouped \row in {0,...,\rows}{
      \pgfplotstablegetelem{\row}{type}\of\intervals
      \edef\type{\pgfplotsretval}
      \pgfplotstablegetelem{\row}{startDate}\of\intervals
      \edef\startdate{\pgfplotsretval}
      \pgfplotstablegetelem{\row}{stopDate}\of\intervals
      \edef\stopdate{\pgfplotsretval}
      \edef\temp{\noexpand\node[gray,anchor=north west,font={\noexpand\footnotesize}] at 
      ({axis cs:\startdate,0}|-{rel axis cs:0,1}) {\type};
      \noexpand\fill[opacity=0.5,gray!50] 
      ({axis cs:\startdate,0}|-{rel axis cs:0,0}) 
      rectangle ({axis cs:\stopdate,0}|-{rel axis cs:0,1});
      }
      \temp
    } 
  }, 
] 
  \addplot table[x=monthlyTimeString,y=numberOfBypassTrips]{\data};
  \addplot table[x=monthlyTimeString,y=numberOfBatteryTrips]{\data};
  \addplot table[x=monthlyTimeString,y=numberOfMainsTrips]{\data};
\end{axis}
\end{tikzpicture}
\end{document}

enter image description here

2
  • Thanks this did the trick. Though is there no prettier way to do this kind of stuff?
    – Reza
    Oct 16, 2018 at 6:01
  • @Reza There might be a way if you do not get this data from a table but from a list. But I am not sure if that works. Basically you may write a code that shades a single list and then apply it to the list with /.list=<list>, perhaps together with some .expanded.
    – user121799
    Oct 16, 2018 at 11:16

You must log in to answer this question.

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