8

Most likely this is trivial for those with some experience in all these expansion issues, but I have a simple question concerning pgfplots. I want to modify its parsing behavior a bit. (Yes, I am aware of the dateplot library, but I did not succeed in adjusting the tricks there to my needs.) This question is motivated by this question. I just want to convert some data, specifically times here, to numbers. This is my attempt.

\documentclass[11pt, twoside, a4paper]{report}
\usepackage{pgfplots}
%\usepgfplotslibrary{dateplot}
\pgfplotsset{compat=1.16}
\usepackage{filecontents}
\begin{filecontents*}{somedata.csv}
Time;AC
00:00:00;-0.4442
00:01:00;-0.4445
\end{filecontents*}
\makeatletter 
\def\myparse#1:#2:#3 #4{%
        \pgf@xa=#1pt
        \pgf@xb=#2pt
        \divide\pgf@xb by60
        \advance\pgf@xa by\pgf@xb
        \pgf@xb=#3pt
        \divide\pgf@xb by3600
        \advance\pgf@xa by\pgf@xb
        \ifdim\pgf@xa<0pt
                \pgf@xa=0pt
        \fi
        \edef#4{\pgf@sys@tonumber\pgf@xa}%
}% 
\newcommand\TimeParse[1]{\myparse#1 \tmp%
\tmp
}
\makeatother

\begin{document}
\TimeParse{00:01:00}
        \begin{tikzpicture}
        \begin{axis}
        %\addplot table [x expr=\TimeParse{\thisrow{Time}}, y=AC, col sep=semicolon] {somedata.csv};
        \end{axis}
        \end{tikzpicture}
\end{document}

Unsurprisingly, the \TimeParse{00:01:00} returns a number. However, once I try to prepend it to the coordinates with x expr=\TimeParse{\thisrow{Time}}, this "parser" fails with an ! Argument of \myparse has an extra }. error, and I am not able to fix that. (It would also be great if an answer of this question could contain a bit of explanation.... This may make it possible to parse more general types of data.;-)

Stefan Pinnow
  • 29,535

1 Answers1

8

Well at first \thisrow{Time} has not the correct format for your \myparse command. You seem to expect that it gets magically expanded before it is inserted in the definition body of \TimeParse command.

At second it is probably a good idea to create an expandable command. That means no \edef and no assignments in the definition. This here seems to work:

\documentclass[11pt, twoside, a4paper]{report}
\usepackage{pgfplots}
%\usepgfplotslibrary{dateplot}
\pgfplotsset{compat=1.16}
\usepackage{filecontents}
\begin{filecontents*}{somedata.csv}
Time;AC
00:00:00;-0.4442
00:01:00;-0.4445
\end{filecontents*}
\usepackage{xfp}
%no idea how to define a command with : in the delimited argument in expl3 ...
\def\marmottimeparseaux#1:#2:#3xxx{\fpeval{#2 / 60 + #1 +(#3/3600)}}
\ExplSyntaxOn
\cs_new:Nn \marmot_timeparse:n { \marmottimeparseaux #1xxx }
\newcommand\TimeParse[1]{\exp_args:Nf\marmot_timeparse:n {#1}}
\ExplSyntaxOff

\begin{document}


        \begin{tikzpicture}
        \begin{axis}
        \addplot table [x expr=\TimeParse{\thisrow{Time}}, y=AC, col sep=semicolon] {somedata.csv};
        \end{axis}
        \end{tikzpicture}
\end{document}

enter image description here

Ulrike Fischer
  • 327,261
  • Thanks! Yes, that is so simple that even I may understand that. (But I can't help to mention that there are tons of \edefs in tikzlibrarypgfplots.dateplot.code.tex, which is why I went this path... ;-) I guess you should now answer this question as well. –  Aug 10 '18 at 22:26
  • I'm not claiming that a non expandable version can't work - I didn't check how the value is processed. But if you can write an expandable version it is better to do this. – Ulrike Fischer Aug 10 '18 at 22:56
  • I could not even make any version, I am very happy with your nice answer! Looking forward to the times in which xparse has more documentation and examples, though. ;-) –  Aug 10 '18 at 23:02