pgfplots:使用 gnuplot 创建的后处理数据

pgfplots:使用 gnuplot 创建的后处理数据

我已经设法使用pgfplots'gnuplot选项来解决隐式方程:

\documentclass{standalone}

\usepackage{tikz,pgfplots}

\begin{document}
  \begin{tikzpicture}
    \begin{loglogaxis}[
      xmin=8e2,
      xmax=1e8,
      ymin=0.008,
      ymax=0.1
      ]
      \addplot[solid,raw gnuplot] gnuplot {
        set xrange [2300:1e8];
        set yrange [0.008:0.1];
        set logscale xy;
        set samples 100;
        f(R,L) = -2*log10(2.51/(R*sqrt(L))+4e-3/3.71)-1/sqrt(L);
        set cont base;
        set cntrparam levels discrete 0;
        unset surface;
        splot f(x,y)
      };
    \end{loglogaxis}
  \end{tikzpicture}
\end{document}

这里的问题是 gnuplot 不对结果进行排序,因此绘图看起来是封闭的。gnuplot在绘制之前,我该如何对生成的数据进行排序pgfplots

我曾尝试将表排序选项传递给 gnuplot:

\addplot[...] gnuplot[sort=true,sort cmp={float <}] {...};

但没用。

我的另一个想法是从我的 tex 文档中调用 gnuplot,但不立即绘图。然后我可以使用 读取数据并pgfplotstable进行处理,但我不知道调用 gnuplot 的便捷方法。我的目标是仅通过一次调用 即可在一个轴环境中生成多个图pfdlatex


我注意到pgfplots1.5.1 确实不是关闭图,但pgfplots1.4.1 可以。但是,坐标仍然没有排序,节点current plot endcurrent plot begin位于同一坐标(这在我的例子中很糟糕)。

答案1

如果我没记错的话,你有两个问题:

问题 1. 如何对 gnuplot 的结果进行排序?

问题2. 为什么1.4版本和1.5版本有区别?

以下是您的答案:

问题 1. 您只能使用 中的宏对结果进行排序pgfplotstable。该sort选项仅适用于\pgfplotstabletypeset。如果您允许两次 pdflatex 传递,它就会起作用:

\begin{tikzpicture}
    \IfFileExists{P.pgf-plot.table}{
        \pgfplotstablesort{\DATA}{P.pgf-plot.table}
    }{}

    \begin{loglogaxis}
    \IfFileExists{P.pgf-plot.table}{
        \addplot[solid,raw gnuplot] table {\DATA};
    }{
        \addplot[solid,raw gnuplot] gnuplot {
            set xrange [2300:1e8];
            set yrange [0.008:0.1];
            set logscale xy;
            set samples 100;
            f(R,L) = -2*log10(2.51/(R*sqrt(L))+4e-3/3.71)-1/sqrt(L);
            set cont base;
            set cntrparam levels discrete 0;
            unset surface;
            splot f(x,y)
        };
    }
    \end{loglogaxis}
\end{tikzpicture}

关键思想是使用 来\IfFileExists区分第一次和第二次运行 - 并使用\pgfplotstablesort将排序后的表格加载到 中\DATA。 绘制它就可以实现您想要的效果。

注意:我将其用P.tex作主 tex 文件名。您需要调整它。

请注意,实验揭示了 pgfplots 中的一个小错误:将\pgfplotstablesort宏移入轴失败。我会修复它(有一个不应激活的回调)。

一个合适的修改是编写一个包含 gnuplot 脚本的临时文件并使用 手动运行 gnuplot \write18{gnuplot datafilename}

问题 2. 从 1.5 版开始,pgfplots 将会填补图中的空白 —— 除非使用\pgfplotsset{compat=1.4}或更新版本,在这种情况下它不会填补空白。

新功能允许在数据文件中添加空行以定义分段函数(即 pgfplots 将在空行处产生间隙)。

使用\pgfplotsset{compat=1.3}将恢复旧的处理并缩小差距。

答案2

这是从 Christian 的回答中得出的部分解决方案。主要缺点是无法在环境中对数据进行排序(因此无法生成数据)loglogaxis,因为pgfplotstablesave在那里是未知的。

\documentclass{standalone}

\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\makeatletter
\newcommand{\gnuplotOptions}[2][pgf-plot]{%
  \newwrite\tempfile%
  \immediate\openout\tempfile=\jobname.#1.gnuplot% 
  \immediate\write\tempfile{set table "\jobname.#1.table";}% 
  \immediate\write\tempfile{set format "\@percentchar.7e";}%
  \immediate\write\tempfile{#2}%
  \immediate\closeout\tempfile%
}
\makeatother

\newcommand{\gnuplot}[1][pgf-plot]{%
  \immediate\write18{gnuplot \jobname.#1.gnuplot}% 
}

\begin{document}
  \begin{tikzpicture}
      \gnuplotOptions{%
        set xrange [2300:1e8];
        set yrange [0.008:0.1];
        set logscale xy;
        set samples 100;
        f(R,L) = -2*log10(2.51/(R*sqrt(L))+4e-3/3.71)-1/sqrt(L);
        set cont base;
        set cntrparam levels discrete 0;
        unset surface;
        splot f(x,y);
      }
      \gnuplot{}
    \pgfplotstablesave[sort=true,sort cmp={float <}]{\jobname.pgf-plot.table}{\jobname.pgf-plot.sorted.table}
    \begin{loglogaxis}
      % cannot create and sort the table here because pgfplotstablesave is unknown in the axis environment (pgfplots 1.5)
      \addplot[raw gnuplot] table[x index=0, y index=1] {\jobname.pgf-plot.sorted.table};
    \end{loglogaxis}
  \end{tikzpicture}
\end{document}

gnuplotOptions命令接受一个可选参数,其作用类似于pgfplotsid键。所有选项都写入 gnuplot 的选项文件。也可以通过使用 将此键传递给 gnuplot,\gnuplot[someid]{}以使 gnuplot 找到正确的选项文件。

\pgfplotstablesave创建用 gnuplot 生成的表的副本,并将排序后的表写回到新文件。

结果像往常一样用 绘制\addplot table

相关内容