我想绘制一个由附加参数 d 参数化的多项式。我对 d 的定义域进行了采样,并将每个样本的多项式系数存储在一个表中:
d a0 a1 a2 a3 a4
0 0.31632 0.038794 -0.637117 0.457322 -0.0940009
0.002 0.316319 0.0387949 -0.637115 0.457321 -0.0940008
0.4 0.130744 0.0171396 -0.292042 0.2209 -0.0479512
...
现在我想将最多 100 个这样的多项式绘制到同一个图中。有没有一种方法不需要我手动编码每个要绘制的多项式或在外部工具中对每个多项式进行采样?(在 Latex 工具链中这样做就可以了。)
总结一下:在我的例子中,表格的行不代表要绘制的坐标,而是我想要绘制的多项式的系数。因此,我不知道如何使用 pgfplot\addplot table
来获得我想要的输出。
代码的效果应该是这样的
\documentclass{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=1.12}
\begin{document}
\begin{tikzpicture}
\begin{axis}[domain=0:2]
\addplot[mark=none] {0.31632 + x*(0.038794 + x*(-0.637117 + x*(0.457322 + x*-0.0940009)))};
\addplot[mark=none] {0.311765 + x*(0.0408345 + x*(-0.633668 + x*(0.454718 + x*-0.0935363)))};
\addplot[mark=none] {0.130744 + x*(0.0171396 + x*(-0.292042 + x*(0.2209 + x*-0.0479512)))};
\end{axis}
\end{tikzpicture}
\end{document}
但无需手动重复。
结果如下:
答案1
这是一种使用方法的方法pgfplotsinvokeforeach
。
有几个重要部分,包括:
% declare a polynomial function
\pgfmathdeclarefunction{mypoly}{6}{%
% #1: a0
% #2: a1
% #3: a2
% #4: a3
% #5: a4
% #6: x
\pgfmathparse{#1+#2*#6%
+#3*#6^2%
+#4*#6^3%
+#5*#6^4}%
}
正如您所见,它定义了您的多项式。
您将看到它在addplot
命令中被调用为
\addplot[domain=0:2,red,thick]{mypoly(\aZero,\aOne,\aTwo,\aThree,\aFour,x)};
完整代码如下:
% arara: pdflatex
% !arara: indent: {overwrite: yes}
\documentclass[tikz]{standalone}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.12}
% read in the coefficients
\pgfplotstableread[col sep=space]{
d a0 a1 a2 a3 a4
0 0.31632 0.038794 -0.637117 0.457322 -0.0940009
1 0.311765 0.0408345 -0.633668 0.454718 -0.0935363
2 0.130744 0.0171396 -0.292042 0.2209 -0.0479512
}\coefficients
% count number of rows
\pgfplotstablegetrowsof\coefficients
\pgfmathsetmacro\numberofrows{\pgfplotsretval-1}
% declare a polynomial function
\pgfmathdeclarefunction{mypoly}{6}{%
% #1: a0
% #2: a1
% #3: a2
% #4: a3
% #5: a4
% #6: x
\pgfmathparse{#1+#2*#6%
+#3*#6^2%
+#4*#6^3%
+#5*#6^4}%
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[domain=0:2]
% loop through the rows of the table
\pgfplotsinvokeforeach{0,...,\numberofrows}{
% define each of a0, a1, a2, a3, a4
% a0
\pgfplotstablegetelem{#1}{[index]1}\of\coefficients
\pgfmathsetmacro{\aZero}{\pgfplotsretval}
% a1
\pgfplotstablegetelem{#1}{[index]2}\of\coefficients
\pgfmathsetmacro{\aOne}{\pgfplotsretval}
% a2
\pgfplotstablegetelem{#1}{[index]3}\of\coefficients
\pgfmathsetmacro{\aTwo}{\pgfplotsretval}
% a3
\pgfplotstablegetelem{#1}{[index]4}\of\coefficients
\pgfmathsetmacro{\aThree}{\pgfplotsretval}
% a4
\pgfplotstablegetelem{#1}{[index]5}\of\coefficients
\pgfmathsetmacro{\aFour}{\pgfplotsretval}
% add the polynomial plot
\addplot[domain=0:2,red,thick]{mypoly(\aZero,\aOne,\aTwo,\aThree,\aFour,x)};
}
\end{axis}
\end{tikzpicture}
\end{document}
答案2
我可能只会使用脚本语言并创建 LaTeX 源代码。以下是 Python 中的一个示例。
#!/usr/bin/env python
import csv
with open('data.csv', 'rb') as csvfile:
coeff = csv.reader(csvfile, delimiter=',')
coeff.next()
for row in coeff:
print("\\addplot[mark=none] {" + row[1] +
" + x * (" + row[2] +
" + x * (" + row[3] +
" + x * (" + row[4] +
" + x * " + row[5] + ")))};")
为了更容易加载系数,我将您的数据转换为适当的 csv 文件。
d,a0,a1,a2,a3,a4
0,0.31632,0.038794,-0.637117,0.457322,-0.0940009
0.002,0.316319,0.0387949,-0.637115,0.457321,-0.0940008
如果你将输出重定向到这样的文件
python createPlots.py > plots.tex
然后您可以稍后使用 在主 tex 文件中加载它\input{}
。
\documentclass{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=1.12}
\begin{document}
\begin{tikzpicture}
\begin{axis}[domain=0:2]
\input{plots.tex}
\end{axis}
\end{tikzpicture}
\end{document}
编辑:
当然,您也可以在 LaTeX 内部运行脚本(需要--shell-escape
)。
\documentclass{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=1.12}
\begin{document}
\begin{tikzpicture}
\begin{axis}[domain=0:2]
\immediate\write18{python createPlots.py > plots.tex}
\input{plots.tex}
\end{axis}
\end{tikzpicture}
\end{document}
编辑2:
因此,这是一个 LuaTeX 解决方案。它还需要正确格式的 csv 文件。
\documentclass{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=1.12}
\usepackage{luacode}
\begin{document}
\begin{tikzpicture}
\begin{axis}[domain=0:2]
\begin{luacode}
firstLineSkipped = false
for line in io.lines("data.csv") do
if firstLineSkipped then
tex.print("\\addplot[mark=none] {" .. line:gsub('.-,','', 1):gsub(",", " + x*(", 4) .. ")))};");
else
firstLineSkipped = true
end
end
\end{luacode}
\end{axis}
\end{tikzpicture}
\end{document}