2

I am facing a problem with setting the limits of my plot in pgfplots. The following script (from an answer here )

\documentclass[border=5mm]{standalone}
\usepackage{pgfplotstable}

\begin{document}
\begin{tikzpicture}
\pgfmathsetmacro{\XMax}{1.1e-3} %changing this to 1.05e-3 gives error
\pgfmathsetmacro{\XMin}{0.95e-3}
\begin{axis}[
  xmin=\XMin,
  xmax=\XMax
]
\pgfplotstableread{
x y dydx
0.96e-3 2 1
0.98e-3 1 -1
0.99e-3 3 0.5
}\mydata
% get number of rows in table
% subtract 1 because row indexing starts at zero
\pgfplotstablegetrowsof{\mydata}
\pgfmathtruncatemacro{\NumRows}{\pgfplotsretval-1}
\pgfmathsetmacro{\AxRange}{\XMax-\XMin}

\pgfplotsinvokeforeach{0,...,\NumRows}{ % loop over rows

  % extract the data from the table
  \pgfplotstablegetelem{#1}{x}\of\mydata
  \pgfmathsetmacro{\X}{\pgfplotsretval}
  \pgfplotstablegetelem{#1}{y}\of\mydata
  \pgfmathsetmacro{\Y}{\pgfplotsretval}
  \pgfplotstablegetelem{#1}{dydx}\of\mydata
  \pgfmathsetmacro{\DYDX}{\pgfplotsretval}

  % calculate start and end of domain for line
  \pgfmathsetmacro{\DomainStart}{\X-\AxRange*0.1}
  \pgfmathsetmacro{\DomainEnd}{\X+\AxRange*0.1}

  % plot
  \addplot +[domain=\DomainStart:\DomainEnd,mark=none,thick,samples=2] {\Y + \DYDX * (x-\X)};
}

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

creates the following figure.

Plot from the script

But changing the value of Xmax to 1.05e-3 gives the following error.

Package pgfplots Warning: running in backwards compatibility mode (unsuitable tick labels; missing features). Consider writing \pgfplotsset{compat=1.14} into your preamble.
 on input line 4.

Runaway definition?
->
./a.tex:40: TeX capacity exceeded, sorry [main memory size=5000000].
\pgfplotsapplistXXpushback@smallbufoverfl ...toka 
                                                  \the \t@pgfplots@tokb \the...
l.40 }

./a.tex:40:  ==> Fatal error occurred, no output PDF file produced!
Transcript written on /Users/manav/Desktop/.texpadtmp/a.log.

Why would the output be so sensitive to the xmax limit? Is there anything that can be done to force this limit without running into the error?

1 Answers1

1

It happens that one runs into such problems with pgf, as the numerical capabilities are a bit limited. Just like in Why tikz fail at computation?, it seems that using \fpeval from the xfp package to do the calculations works here as well. I used that also to calculate the y-values of the endpoints of the lines, and used \addplot coordinates to plot the lines. This works with a smaller range as well, here with xmax=1.0e-3.

enter image description here

%%%%%%%%
%% the following only for example
\RequirePackage{filecontents}
% the filecontents environment writes its content to the specified file
\begin{filecontents*}{data.dat}
x y dydx
0.96e-3 2 1
0.98e-3 1 -1
0.99e-3 3 0.5
\end{filecontents*}
%%%%%%%

\documentclass[border=5mm]{standalone}
\usepackage{pgfplotstable}
\usepackage{xfp}
\begin{document}
\begin{tikzpicture}
\pgfplotstableread{data.dat}\mydata
% get number of rows in table
% subtract 1 because row indexing starts at zero
\pgfplotstablegetrowsof{\mydata}
\pgfmathtruncatemacro{\NumRows}{\pgfplotsretval-1}

\begin{axis}[
  xmin=0.95e-3,
  xmax=1.0e-3,
  samples=2
]

\edef\AxRange{\fpeval{\pgfkeysvalueof{/pgfplots/xmax}-\pgfkeysvalueof{/pgfplots/xmin}}}

\pgfplotsinvokeforeach{0,...,\NumRows}{ % loop over rows

  % extract the data from the table
  \pgfplotstablegetelem{#1}{x}\of\mydata
  \pgfmathsetmacro{\X}{\pgfplotsretval}
  \pgfplotstablegetelem{#1}{y}\of\mydata
  \pgfmathsetmacro{\Y}{\pgfplotsretval}
  \pgfplotstablegetelem{#1}{dydx}\of\mydata
  \pgfmathsetmacro{\DYDX}{\pgfplotsretval}

  % calculate start and end of domain for line
  \edef\XStart{\fpeval{\X-\AxRange*0.1}}
  \edef\XEnd{\fpeval{\X+\AxRange*0.1}}
  % calculate start and end y-values of line
  \edef\YStart{\fpeval{\Y + \DYDX * (\XStart-\X)}}
  \edef\YEnd{\fpeval{\Y + \DYDX * (\XEnd-\X)}}

  % plot
  \addplot +[mark=none,thick] coordinates {(\XStart, \YStart) (\XEnd, \YEnd)};
}

\end{axis}
\end{tikzpicture}
\end{document}
Torbjørn T.
  • 206,688
  • Thanks! This works fine. One question: why is \addplot coordinates preferred here as opposed to the domain approach in the original code? – user6593 Jul 06 '18 at 11:30
  • @user6593 Not sure it matters all that much, to be honest. This way that calculation is handled by xfp as well, though you might not see any difference in the output. – Torbjørn T. Jul 06 '18 at 11:38
  • I tried replacing the addplot line with this \addplot +[domain=\XStart:\XEnd,mark=none,samples=2] {\Y + \DYDX * (x-\X)}; and it gave the same result. – user6593 Jul 06 '18 at 11:41
  • I am facing another issue: modifying the y values in the data to 2.e-6 1.e-6 3.e-6 makes all plots to start from zero. It appears that there is a lower limit that pgfplots can handle. I tried reducing the exponent from e-0 to e-6 and this problem showed up at e-5. Is there a way to handle these numbers? – user6593 Jul 06 '18 at 12:24
  • @user6593 Can't say, that works fine here. – Torbjørn T. Jul 06 '18 at 18:05