由于特定的 xmax 限制导致 pgfplots 内存错误

由于特定的 xmax 限制导致 pgfplots 内存错误

我在设置 pgfplots 中的绘图限制时遇到了问题。以下脚本(来自答案这里

\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}

创建下图。

剧本情节

但是将 Xmax 的值更改为 1.05e-3 会出现以下错误。

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.

为什么输出对 xmax 限制如此敏感?有什么办法可以强制执行此限制而不会出现错误吗?

答案1

在使用 时,有时会遇到这样的问题pgf,因为数值能力有点有限。就像在为什么 tikz 计算失败?,似乎使用包\fpeval中的xfp进行计算在这里也有效。我还使用它来计算线条端点的 y 值,并用它\addplot coordinates来绘制线条。这也适用于较小的范围,这里是xmax=1.0e-3

在此处输入图片描述

%%%%%%%%
%% 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}

相关内容