我已经设法使用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
。
我注意到pgfplots
1.5.1 确实不是关闭图,但pgfplots
1.4.1 可以。但是,坐标仍然没有排序,节点current plot end
和current 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
命令接受一个可选参数,其作用类似于pgfplots
的id
键。所有选项都写入 gnuplot 的选项文件。也可以通过使用 将此键传递给 gnuplot,\gnuplot[someid]{}
以使 gnuplot 找到正确的选项文件。
\pgfplotstablesave
创建用 gnuplot 生成的表的副本,并将排序后的表写回到新文件。
结果像往常一样用 绘制\addplot table
。