4

What I want to achieve is a graph, which shows the working hours per day. Input should be the triple of date, arrival time and leaving time. The x-axis holds the dates and the y-axis shows the working time - maybe as a bar somehow. Following code works so far with dates in x-axis and floats in the y-axis.

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfcalendar}
\usepackage{pgfplotstable}
\usetikzlibrary{pgfplots.dateplot}
\usepgfplotslibrary{dateplot}
% File content zeiten_float.dat
%   datum kommt geht
%   2016-01-04 6.30 16.10
%   2016-01-05 6.40 16.20
%   2016-01-07 6.20 16.30
%   2016-01-08 6.10 16.40
%   2016-01-11 6.30 16.50
%   2016-01-12 6.50 16.10
%   2016-01-13 6.40 16.20
%   2016-01-14 6.10 16.30
\begin{document}
    \begin{tikzpicture}
        \begin{axis}[
            date coordinates in=x,
            xticklabel={\day.\month.}
            ]
            \addplot table[x=datum,y=kommt] {zeiten_float.dat};
            \addplot table[x=datum,y=geht]  {zeiten_float.dat};
        \end{axis}
    \end{tikzpicture}
\end{document}

Dates with floats

Now the code, which fails. The difference compared to the ybove code is that I replaced the floats with the natural time format (refer to the comment block in the code) and I added the line to convert this time format for the y-axis, but there is the bug.

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfcalendar}
\usetikzlibrary{pgfplots.dateplot}
\usepgfplotslibrary{dateplot}
% File content zeiten.dat
%   datum kommt geht
%   2016-01-04 06:30 16:10
%   2016-01-05 06:40 16:20
%   2016-01-07 06:20 16:30
%   2016-01-08 06:10 16:40
%   2016-01-11 06:30 16:50
%   2016-01-12 06:50 16:10
%   2016-01-13 06:40 16:20
%   2016-01-14 06:10 16:30
\begin{document}
    \begin{tikzpicture}
        \begin{axis}[
            date coordinates in=x,
            xticklabel={\day.\month.},
            date coordinates in=y,
            yticklabel={\hour:\minute}
            ]
            \addplot table[x=datum,y=kommt] {zeiten.dat};
            \addplot table[x=datum,y=geht]  {zeiten.dat};
        \end{axis}
    \end{tikzpicture}
\end{document}

It results in the error messages:

Error Messages

  • 2
    You didn't load the pgfplots package. :) You will still have some errors, but it will remove some (the first one for example). – Alenanno Jan 14 '16 at 23:42
  • This seem can't work. \hour and \minute are part of data coordinates, so they can be part only one axes and not two, as you like to achieve. – Zarko Jan 15 '16 at 6:10
  • Thanks for the help. I will check for the missing package to be loaded. The crucial point seems to be the fact that it is not possible to have data coordinates on two axes. Thanks for the hints. – Harald Lichtenstein Jan 15 '16 at 12:39
4

First of all, about packages/libraries you loaded: both \usetikzlibrary{pgfplots.dateplot} and \usepgfplotslibrary{dateplot} loads tikzlibrarypgfplots.dateplot.code.tex, which then loads pgfcalendar.code.tex, which \usepackage{pgfcalendar} loads. And you need pgfplots, which pgfplotstable loads.

Anyway, dateplot expects "complete" time stamp. It likes 2016-01-04 06:30 but dislikes 06:30. So... we could just write our own! (The structure is basically copied from the definition of date coordinates in in tikzlibrarypgfplots.dateplot.code.tex)

\documentclass[tikz]{standalone}
\usepackage{filecontents,pgfplots}
\usepgfplotslibrary{dateplot}

\begin{filecontents}{zeiten.dat}
    datum kommt geht
    2016-01-04 06:30 16:10
    2016-01-05 06:40 16:20
    2016-01-07 06:20 16:30
    2016-01-08 06:10 16:40
    2016-01-11 06:30 16:50
    2016-01-12 06:50 16:10
    2016-01-13 06:40 16:20
    2016-01-14 06:10 16:30
\end{filecontents}

\def\pgfplotslibdateplothour:minutetofloat#1:#2.{
    \pgfmathparse{#1+#2/60}
}
\def\pgfplotslibdateplofloattothour:minute#1.{
    \pgfmathsetmacro\hour{int(floor(#1))}
    \pgfmathsetmacro\minute{int((#1-\hour)*60)}
    \ifnum\hour<10\edef\hour{0\hour}\fi
    \ifnum\minute<10\edef\minute{0\minute}\fi
}
\pgfplotsset{
    /pgfplots/time coordinates in/.code={%
        \pgfkeysdef{/pgfplots/#1 coord trafo}{%
            \pgfplotslibdateplothour:minutetofloat##1.
        }
        \pgfkeysdef{/pgfplots/#1 coord inv trafo}{
            \pgfplotslibdateplofloattothour:minute##1.
        }
    }
}
\begin{document}
    \begin{tikzpicture}
        \begin{axis}[
            date coordinates in=x,
            xticklabel={\day.\month.},
            time coordinates in=y,
            yticklabel={\hour:\minute}
            ]
            \addplot table[x=datum,y=kommt] {zeiten.dat};
            \addplot table[x=datum,y=geht]  {zeiten.dat};
        \end{axis}
    \end{tikzpicture}
\end{document}
  • Thanks for this extensive support. That's what I was looking for. I have to study the definitions, because I'm not so familiar with it, but it's a great basis to go furher, again may thanks. – Harald Lichtenstein Jan 19 '16 at 20:35
  • I just tried to use your code. But there seems to be an issue with the hour numbers: As they always have a leading zero, if < 10, they are interpreted as octal numbers. This leads to errors for 08:.. and 09:.. Would be great, if you could improve your code! (Or should I make a new question?) – Faekynn Feb 4 '16 at 10:14
  • 1
    @Faekynn A stupid, immediate way is to replace \pgfmathparse{#1+#2/60} by \pgfmathparse{1#1+#2/60-100}. I will check how official librarys resolve this. – Symbol 1 Feb 4 '16 at 10:18
  • thanks, that works! another possibility might be described here: tex.stackexchange.com/a/52233/44467 – Faekynn Feb 4 '16 at 12:51

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.