1

I would like to compare several years of data by month/date on x-axis with just a tick labels being months. Would I call this over plotting? My data would have files for each year of the form: year-month-date (2016-12-26) and a value. Each file would be for a preceding year. I used an example from the gallery as a starting point with the x-axis defined by:

\begin{axis}[date coordinates in=x, xticklabel={\day.\month.},

Using this example, multiple years of data just plot as I would expect.

How do I over plot multiple years of data on the same axis with regards to month/day or just months?

My first thought was to change the year in each file to the same value, but I feel that neuters my data sets. Might there be a way to neglect the year of a date entry? Somebody must have come across this before.

Best regards, Dave.

3

As I understand it, the following code does what you're after. What I do is read in the original data to a table, and then make a new column where the year is constant (I used year 0, but that you can change.) This is the same as the third option of the old answer (see below), but I modified the xticks a bit.

\documentclass[border=5mm,tikz]{standalone}
% dummy data files
\usepackage{filecontents}
\begin{filecontents}{year1.dat}
t,y
2014-01-12,1
2014-02-12,2
2014-03-1,1
2014-03-10,1.2
2014-03-18,1.4
2014-04-12,3
2014-05-12,1.5
2014-06-12,1
2014-07-1,2
2014-07-12,2.5
2014-07-20,2.2
2014-08-12,1
2014-09-12,3
2014-10-12,1.5
2014-11-12,2.5
2014-12-12,2
\end{filecontents}
\begin{filecontents}{year2.dat}
t,y
2015-01-12,1.3
2015-02-12,2.4
2015-03-12,1.2
2015-04-12,3.5
2015-05-12,1.9
2015-06-12,1.2
2015-07-12,2.2
2015-08-12,1.4
2015-09-12,3.3
2015-10-12,1.8
2015-11-12,2.1
2015-12-12,2.2
\end{filecontents}

\usepackage{pgfplots,pgfplotstable}
\usepgfplotslibrary{dateplot}

% count for calculations
\newcount\julianday

% macro for reading files and adding column
% #1: filename
% #2: macroname to save table to
\newcommand\ReadFileYearZero[2]{%
\pgfplotstableread[col sep=comma]{#1}#2
\pgfplotstablecreatecol[
    create col/assign/.code={
        % convert the number of the current row and save it to `\julianday'
        \pgfcalendardatetojulian{\thisrow{t}}{\julianday}
        % convert to year-month-day
        \pgfcalendarjuliantodate{\julianday}{\Year}{\Month}{\Day}
        % make new entry in yearzero-column, with 0-<month>-<day>
        \edef\entry{0-\Month-\Day}
        \pgfkeyslet{/pgfplots/table/create col/next content}\entry
        }
    ]{newday}{#2}}

% read in files - third option
\ReadFileYearZero{year1.dat}{\dataA}
\ReadFileYearZero{year2.dat}{\dataB}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
  width=10cm,
  height=6cm,
  date coordinates in=x,
  xlabel=Month,
  xtick={ % ticks at first day of each month
    0-1-1,
    0-2-1,
    0-3-1,
    0-4-1,
    0-5-1,
    0-6-1,
    0-7-1,
    0-8-1,
    0-9-1,
    0-10-1,
    0-11-1,
    0-12-1},
  xticklabel={\pgfcalendarmonthshortname{\month}}, % short name of month for ticklabels
  xticklabel style={font=\footnotesize},
]

\addplot table [x=newday,y=y] {\dataA};
\addplot table [x=newday,y=y] {\dataB};

\addlegendentry{2014}
\addlegendentry{2015}

\end{axis}
\end{tikzpicture}
\end{document}

Output:

enter image description here

Old answer

The code below illustrates three different cases. I'm not really sure how your data looks, but hopefully one of these could work for you. The three cases are:

  1. Assuming you have one value per month in every year, and each year has is complete, i.e. there are no missing months in the data file, this becomes quite simple:

    \addplot table [x expr=\coordindex+1,y=y,col sep=comma] {year1.dat};
    

    x expr is used when you want some calculation for the x-coordinate. \coordindex is a count of the datapoints, starting at zero. So for twelve data points, this becomes 1,2,...,12.

  2. This also assumes one value per month, but it extracts the month number from the data, so missing months are handled.

  3. This creates a new date column in the data table, where the year is set to zero. Hence, this is perhaps the most flexible version.

enter image description here

\documentclass[border=5mm,tikz]{standalone}
% dummy data files
\usepackage{filecontents}
\begin{filecontents}{year1.dat}
t,y
2014-01-12,1
2014-02-12,2
2014-03-12,1
2014-04-12,3
2014-05-12,1.5
2014-06-12,1
2014-07-12,2
2014-08-12,1
2014-09-12,3
2014-10-12,1.5
2014-11-12,2.5
2014-12-12,2
\end{filecontents}
\begin{filecontents}{year2.dat}
t,y
2015-01-12,1.3
2015-02-12,2.4
2015-03-12,1.2
2015-04-12,3.5
2015-05-12,1.9
2015-06-12,1.2
2015-07-12,2.2
2015-08-12,1.4
2015-09-12,3.3
2015-10-12,1.8
2015-11-12,2.1
2015-12-12,2.2
\end{filecontents}

\usepackage{pgfplots,pgfplotstable}
\usepgfplotslibrary{dateplot}

% count for calculations
\newcount\julianday

% for second option
% macro for reading files and adding column
% #1: filename
% #2: macroname to save table to
% note that the method is rather roundabout, and there
% are very likely better ways of achieving the same
\newcommand\ReadAndGetMonth[2]{%
\pgfplotstableread[col sep=comma]{#1}#2
\pgfplotstablecreatecol[
    create col/assign/.code={
        % convert the number of the current row and save it to `\julianday'
        \pgfcalendardatetojulian{\thisrow{t}}{\julianday}
        % convert to year-month-day
        \pgfcalendarjuliantodate{\julianday}{\Year}{\Month}{\Day}
        % save month value to new column
        \edef\entry{\Month}
        \pgfkeyslet{/pgfplots/table/create col/next content}\entry
        }
    ]{month}{#2}}


% for third option
% macro for reading files and adding column
% #1: filename
% #2: macroname to save table to
\newcommand\ReadFileYearZero[2]{%
\pgfplotstableread[col sep=comma]{#1}#2
\pgfplotstablecreatecol[
    create col/assign/.code={
        % convert the number of the current row and save it to `\julianday'
        \pgfcalendardatetojulian{\thisrow{t}}{\julianday}
        % convert to year-month-day
        \pgfcalendarjuliantodate{\julianday}{\Year}{\Month}{\Day}
        % make new entry in yearzero-column, with 0-<month>-<day>
        \edef\entry{0-\Month-\Day}
        \pgfkeyslet{/pgfplots/table/create col/next content}\entry
        }
    ]{newday}{#2}}

% read in files - second option
\ReadAndGetMonth{year1.dat}{\dataA}
\ReadAndGetMonth{year2.dat}{\dataB}

% read in files - third option
\ReadFileYearZero{year1.dat}{\dataAa}
\ReadFileYearZero{year2.dat}{\dataBb}

\begin{document}

% first option -- assuming one value per month, always
\begin{tikzpicture}
\begin{axis}[
  width=10cm,
  height=6cm,
  xlabel=Month,
  xtick=data,
  xticklabel={\pgfcalendarmonthshortname{\tick}}, % 1-> Jan, etc.
  xticklabel style={font=\footnotesize},
]

% \coordindex starts counting from 0
\addplot table [x expr=\coordindex+1,y=y,col sep=comma] {year1.dat};
\addplot table [x expr=\coordindex+1,y=y,col sep=comma] {year2.dat};

\addlegendentry{2014}
\addlegendentry{2015}

\end{axis}
\end{tikzpicture}

% second option - month alone
\begin{tikzpicture}
\begin{axis}[
  width=10cm,
  height=6cm,
  xlabel=Month,
  xtick={1,...,12},
  xticklabel={\pgfcalendarmonthshortname{\tick}},
  xticklabel style={font=\footnotesize},
]

\addplot table [x=month,y=y] {\dataA};
\addplot table [x=month,y=y] {\dataB};

\addlegendentry{2014}
\addlegendentry{2015}

\end{axis}
\end{tikzpicture}

% third option  - month and day in year 0
\begin{tikzpicture}
\begin{axis}[
  width=10cm,
  height=6cm,
  date coordinates in=x,
  xlabel=Month,
%  xtick={ % if you wish to set cticks at specific dates
%    0-1-12, % year-month-day
%    0-2-12,
%    0-3-12,
%    0-4-12,
%    0-5-12,
%    0-6-12,
%    0-7-12,
%    0-8-12,
%    0-9-12,
%    0-10-12,
%    0-11-12,
%    0-12-12},
  xticklabel={\day.\month},
  xticklabel style={font=\footnotesize},
]

\addplot table [x=newday,y=y] {\dataAa};
\addplot table [x=newday,y=y] {\dataBb};

\addlegendentry{2014}
\addlegendentry{2015}

\end{axis}
\end{tikzpicture}
\end{document}
  • Some inspiration/code was borrowed from Stefan Pinnow's answer at tex.stackexchange.com/questions/263410/… – Torbjørn T. Dec 28 '16 at 21:07
  • My data is for each day with some seasonal data missing/ending for up to 5 years (or more). The third option may be what I'm looking for. I believe that my initial thought was to read the original data but change the year to a common value and plot the month-day~y data where my x-tick are just the months. Could another option be to over plot with an x-axis scaled for each year (axis opacity set =>0)? Much appreciated...Dave. – user50506 Dec 29 '16 at 3:53
  • @user50506 Sorry, was confused by your saying "or just months", so I thought you had monthly data. The third option does exactly what you say there, it just needs a small adjustment for the ticks. I'll edit in a bit. – Torbjørn T. Dec 29 '16 at 8:23
  • The above code is a great jumping off point, so I used that as the basis for my data, adding external file reading. So far so good. My data has a span of September to August, so the January to December range leaves a bimodal plot with little to nothing from May to August (Winter data). How would I change the range to September to May or something like this? – user50506 Feb 14 '17 at 5:13
  • @user50506 I don't know, my initial attempts failed. I suggest you make a new question about that problem. You can refer to this question for reference, and even use my code as an example if you like. – Torbjørn T. Feb 14 '17 at 8:47

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.