2

I am using pgfplots to draw a graph and I would like to modify the abscissa values of the data when they are plotted. I am currently using x filter/.code={\pgfmathparse{1/#1} \pgfmathresult} to take the inverse of the x values. However, for this math operation, it seems that there is a lack of precision. Here is the MWE where the output is not what is wanted:

\documentclass[a4paper]{article}
\usepackage{pgfplots}

\begin{document}

\begin{tikzpicture}
\begin{axis}[%
width=10cm,
height=5cm,
]
\addplot [x filter/.code={\pgfmathparse{1/#1} \pgfmathresult}]
  table[row sep=crcr]{%
665.123474243553    50.0709210000000\\ 
665.124802332690    49.6678125000000\\ 
665.126130403923    49.7686245000000\\ 
665.127458480460    49.7501640000000\\ 
665.128786585510    49.6496310000000\\ 
665.130114672653    49.8061035000000\\ 
665.131442788313    50.1225825000000\\ 
665.132770886063    49.5357525000000\\ 
665.134099012330    49.4506110000000\\ 
665.135427120687    50.0079600000000\\ 
665.136755257560    49.0017465000000\\ 
665.138083376527    49.5523995000000\\ 
665.139411524010    49.7646720000000\\ 
665.140739653583    49.7826210000000\\ 
665.142067788460    49.3249215000000\\ 
665.143395951857    48.9346470000000\\ 
665.144724097340    48.6674580000000\\ 
665.146052271343    48.2280330000000\\ 
665.147380427437    46.8564690000000\\ 
665.148708612050    46.2079800000000\\ 
665.150036778750    44.7215610000000\\ 
665.151364973970    44.2429365000000\\ 
665.152693151283    43.3782690000000\\ 
665.154021357110    44.1923910000000\\ 
665.155349545030    44.8409730000000\\ 
665.156677761467    45.3737235000000\\ 
665.158005959997    46.7979255000000\\ 
665.159334163827    47.2520910000000\\ 
665.160662396177    48.7288845000000\\ 
665.161990610620    48.5122410000000\\ 
665.163318853580    49.2502890000000\\ 
665.164647078630    48.5547885000000\\ 
665.165975332200    49.2531720000000\\ 
665.167303567860    50.3161155000000\\ 
665.168631832037    49.4624685000000\\ 
665.169960078307    49.6258695000000\\ 
665.171288353093    50.0582730000000\\ 
665.172616609973    49.7700195000000\\ 
665.173944872157    49.7608590000000\\ 
665.175273162857    49.8229830000000\\ 
665.176601435650    49.8743190000000\\ 
665.177929736963    49.8491160000000\\
};

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

Is there a way to improve the precision?

EDIT SOLUTION:

\documentclass[a4paper]{article}
\usepackage{pgfplots,xfp}

\begin{document}

\begin{tikzpicture}
\begin{axis}[%
width=10cm,
height=5cm,
xticklabel style={/pgf/number format/fixed,/pgf/number format/precision=6, rotate=45}
]
\addplot [x filter/.code={\def\pgfmathresult{\fpeval{1/#1}}}]
  table[row sep=crcr]{%
665.123474243553    50.0709210000000\\ 
665.124802332690    49.6678125000000\\ 
665.126130403923    49.7686245000000\\ 
665.127458480460    49.7501640000000\\ 
665.128786585510    49.6496310000000\\ 
665.130114672653    49.8061035000000\\ 
665.131442788313    50.1225825000000\\ 
665.132770886063    49.5357525000000\\ 
665.134099012330    49.4506110000000\\ 
665.135427120687    50.0079600000000\\ 
665.136755257560    49.0017465000000\\ 
665.138083376527    49.5523995000000\\ 
665.139411524010    49.7646720000000\\ 
665.140739653583    49.7826210000000\\ 
665.142067788460    49.3249215000000\\ 
665.143395951857    48.9346470000000\\ 
665.144724097340    48.6674580000000\\ 
665.146052271343    48.2280330000000\\ 
665.147380427437    46.8564690000000\\ 
665.148708612050    46.2079800000000\\ 
665.150036778750    44.7215610000000\\ 
665.151364973970    44.2429365000000\\ 
665.152693151283    43.3782690000000\\ 
665.154021357110    44.1923910000000\\ 
665.155349545030    44.8409730000000\\ 
665.156677761467    45.3737235000000\\ 
665.158005959997    46.7979255000000\\ 
665.159334163827    47.2520910000000\\ 
665.160662396177    48.7288845000000\\ 
665.161990610620    48.5122410000000\\ 
665.163318853580    49.2502890000000\\ 
665.164647078630    48.5547885000000\\ 
665.165975332200    49.2531720000000\\ 
665.167303567860    50.3161155000000\\ 
665.168631832037    49.4624685000000\\ 
665.169960078307    49.6258695000000\\ 
665.171288353093    50.0582730000000\\ 
665.172616609973    49.7700195000000\\ 
665.173944872157    49.7608590000000\\ 
665.175273162857    49.8229830000000\\ 
665.176601435650    49.8743190000000\\ 
665.177929736963    49.8491160000000\\
};

\end{axis}
\end{tikzpicture}
\end{document}
Alex
  • 23
  • Use x filter/.code={\pgfmathparse{1/665.161990610620-(#1-665.161990610620)/665.161990610620} \pgfmathresult}. This is the first order Taylor expansion and works for your version (I think). You can go to higher orders if needed. –  Aug 22 '19 at 20:43
  • Thanks! This surely works but I guess that it can be difficult to implement in a more general case besides the 1/x function. – Alex Aug 25 '19 at 18:45

1 Answers1

1

With xfp I get this

enter image description here

\documentclass[a4paper]{article}
\usepackage{pgfplots,xfp}

\begin{document}

\begin{tikzpicture}
\begin{axis}[%
width=10cm,
height=5cm,
]
\addplot [x filter/.code={\fpeval{1/#1}}]
  table[row sep=crcr]{%
665.123474243553    50.0709210000000\\
665.124802332690    49.6678125000000\\
665.126130403923    49.7686245000000\\
665.127458480460    49.7501640000000\\
665.128786585510    49.6496310000000\\
665.130114672653    49.8061035000000\\
665.131442788313    50.1225825000000\\
665.132770886063    49.5357525000000\\
665.134099012330    49.4506110000000\\
665.135427120687    50.0079600000000\\
665.136755257560    49.0017465000000\\
665.138083376527    49.5523995000000\\
665.139411524010    49.7646720000000\\
665.140739653583    49.7826210000000\\
665.142067788460    49.3249215000000\\
665.143395951857    48.9346470000000\\
665.144724097340    48.6674580000000\\
665.146052271343    48.2280330000000\\
665.147380427437    46.8564690000000\\
665.148708612050    46.2079800000000\\
665.150036778750    44.7215610000000\\
665.151364973970    44.2429365000000\\
665.152693151283    43.3782690000000\\
665.154021357110    44.1923910000000\\
665.155349545030    44.8409730000000\\
665.156677761467    45.3737235000000\\
665.158005959997    46.7979255000000\\
665.159334163827    47.2520910000000\\
665.160662396177    48.7288845000000\\
665.161990610620    48.5122410000000\\
665.163318853580    49.2502890000000\\
665.164647078630    48.5547885000000\\
665.165975332200    49.2531720000000\\
665.167303567860    50.3161155000000\\
665.168631832037    49.4624685000000\\
665.169960078307    49.6258695000000\\
665.171288353093    50.0582730000000\\
665.172616609973    49.7700195000000\\
665.173944872157    49.7608590000000\\
665.175273162857    49.8229830000000\\
665.176601435650    49.8743190000000\\
665.177929736963    49.8491160000000\\
};

\end{axis}
\end{tikzpicture}
\end{document}
Ulrike Fischer
  • 327,261
  • I cannot use the xfp package, it seems that it is not available in my version of texlive (TeX Live 2016/Debian). I even try to use it by downloading the packages but there a lot of errors.

    However, your output seems weird: \fpeval{1/#1} seems not to take the inverse of #1, there is no change (the x axis is the same).

    – Alex Aug 22 '19 at 18:12
  • You could try the fpu library of pgf, it should be more precise too. And perhaps update your tex system. 2016 is rather old. I didn't really look at your code, I don't have the time for it, I simply replaced one part. – Ulrike Fischer Aug 22 '19 at 18:24
  • @Alex x filter/.code has to modify \pgfmathresult. Something like x filter/.code={\def\pgfmathresult{\fpeval{1/#1}}} seems to work. (And you need for example xticklabel style={/pgf/number format/fixed,/pgf/number format/precision=10, rotate=45} to tell the ticks apart.) – Torbjørn T. Aug 24 '19 at 06:45
  • From the manual: "It is allowed that filters do not change \pgfmathresult. In this case, the unfiltered coordinate will be used." – Torbjørn T. Aug 24 '19 at 06:47
  • Thanks Torbjørn T.! I have tried this on overleaf and this works. I have edited my first post and added the solution. – Alex Aug 25 '19 at 18:41