5

I have some data with a huge offset that I want to plot. Im using PGF plots, where it's possible to subtract the offset from a whole row in my data.

This works when the offset isn't too big, and/or the delta between ticks isn't to small. otherwise the plot will be all twisted.

See folowing MWE:

\documentclass[border=4mm]{standalone}
\usepackage{pgfplots,filecontents}

\begin{filecontents*}{data.dat}
X   Y
149038832.9 19
149038835.1 18
149038837.3 17
149038839.5 16
149038841.7 15
149038843.9 14
149038846.1 13
149038848.3 12
149038850.5 11
149038852.7 10
149038854.9 9
149038857.1 8
149038859.3 7
149038861.5 6
149038863.7 5
149038865.9 4
149038868.1 3
149038870.3 2
149038872.5 1
149038874.7 0
\end{filecontents*}

\begin{document}
\begin{tikzpicture}
    \begin{axis}[]
        \addplot table[x expr=(\thisrowno{0}-149038800),y=Y] {data.dat};
    \end{axis}
\end{tikzpicture}
\end{document}

This example was supposed to give a plot with a straight line, but the result are as follows: enter image description here

EDIT:

Post-processing the data isn't a possibility, because I'm not allowed to make changes to the datafiles.

However, arcording to this(p.5), it's possible to change the mathematical engine from usepackage pgfmath(default) to fp, which should extend the fixed-point arithmetic. I just don't know how to do this.

  • 1
    I would guess this is a result of the limited precision of math in TeX. You should consider using an external script to pre-process the data first. You can look on this site (a Google search might be more fruitful with site:tex.stackexchange.com) for other information about floating point arithmetic – darthbith Dec 15 '15 at 13:53
5

It is possible to use another math engine in the following manner

\documentclass[border=4mm]{standalone}
\usepackage{pgfplots,filecontents}
\usepackage{xintexpr}

\begin{filecontents*}{data.dat}
X   Y
149038832.9 19
149038835.1 18
149038837.3 17
149038839.5 16
149038841.7 15
149038843.9 14
149038846.1 13
149038848.3 12
149038850.5 11
149038852.7 10
149038854.9 9
149038857.1 8
149038859.3 7
149038861.5 6
149038863.7 5
149038865.9 4
149038868.1 3
149038870.3 2
149038872.5 1
149038874.7 0
\end{filecontents*}

\begin{document}
\begin{tikzpicture}
    \begin{axis}[]
        \addplot table[x expr=({\xinttheiexpr[1]\thisrowno{0}-149038800\relax}),y=Y] {data.dat};
    \end{axis}
\end{tikzpicture}
\end{document}

I explain the syntax:

  1. \xinttheiexpr[d] ... \relax does exact computations with scientific numbers or fractions (no limit on number of digits, but concretely works best with up to a few hundred digits per number) then truncates rounds to d digits after decimal mark. So far, apart from square root (by default, with 16 digits of precision; but sqrt(x,P) will have P digits of precision) no non-algebraic functions implemented though. It is also possible to use only macros from package xintfrac, but the expression syntax is easier to use.

  2. I needed braces to trick the `TikZ parsing it seems.

Output:

enter image description here

  • Ha, that's going to come in really handy! – Jake Dec 16 '15 at 20:40
  • @Jake I was lucky no sin, no exp... ;-) – user4686 Dec 16 '15 at 20:41
  • That's your package? I'm impressed! – Jake Dec 16 '15 at 20:54
  • 1
    @Jake yes, thanks. It originated as a package for expandable calculations on big integers. Extension to arbitrary precision floats is in its infancy yet. I haven't even NaN's yet. – user4686 Dec 16 '15 at 20:57
4

To work around the limited precision and the restriction that you can't preprocess the data file, you could truncate the number at the string level before plotting it. You can do that using by using \pgfplotstablemodifyeachcolumnelement to loop over the rows, and then extracting the rightmost characters using \StrRight{\cell}{6}[\result] (from the xstring package):

\documentclass[border=4mm]{standalone}
\usepackage{pgfplots,filecontents, xstring, pgfplotstable}

\begin{filecontents*}{data.dat}
X   Y
149038832.9 19
149038835.1 18
149038837.3 17
149038839.5 16
149038841.7 15
149038843.9 14
149038846.1 13
149038848.3 12
149038850.5 11
149038852.7 10
149038854.9 9
149038857.1 8
149038859.3 7
149038861.5 6
149038863.7 5
149038865.9 4
149038868.1 3
149038870.3 2
149038872.5 1
149038874.7 0
\end{filecontents*}

\pgfplotstableread{data.dat}\datatable
    \pgfplotstablemodifyeachcolumnelement{X}\of\datatable\as\cell{%
    \StrRight{\cell}{6}[\result]%
    \edef\cell{\result}%
}

\begin{document}
\begin{tikzpicture}
    \begin{axis}[]
        \addplot table[x expr=(\thisrowno{0}-8800),y=Y] {\datatable};
    \end{axis}
\end{tikzpicture}
\end{document}
  • I like this solution, but is I cant guarantee that there is the same amount of decimal every time. So is possible to grap the data by cutting away from left instead? – Rasmus Dec 16 '15 at 13:36
  • nevermind I did figure it out myself: \StrGobbleLeft{\cell}{5}[\result]% – Rasmus Dec 16 '15 at 13: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.