我正在尝试采用基于脚本的方式来回答我的常设问题pgfplots 中误差的自动计算,而且我有一个可行的解决方案。
使用 Python,我将给定的数据集转换为对我朋友的领域有意义的内容。如果您对脚本感兴趣,下面将重现该脚本。我能够使用一系列命令在 LaTeX 中简化其使用,理想情况下,我希望使用\newcommand
或类似的宏将其本身转换为宏。不幸的是,我遇到了无法解释或解决的错误。我正在使用包tikz
、pgfplots
和bashful
。 bashful
这是给我带来问题的那个。
error.py
(完美运行)
def sqrt(n):
return n**.5
def avg(nums):
return sum(nums)/len(nums)
def stddev(nums):
s = sum(nums)
a = avg(nums)
s2 = sum([(n - a)**2 for n in nums])
return sqrt(s2/len(nums))
def stderr(nums):
return stddev(nums)/sqrt(len(nums))
lines = list()
import sys
with open(sys.argv[1],'r') as f:
lines = f.readlines()
data = list()
for i in range(len(lines)):
if lines[i][0].isdigit():
toks = lines[i].split()
data.append(map(int,toks))
data = [(data[0][i], [l[i] for l in data[1:]]) for i in range(len(data[0]))]
for (val, nums) in data:
print val, avg(map(float,nums)), stderr(map(float,nums))
手动命令
\bash[stdoutFile=plots/mydata.table.digest]
python error.py plots/mydata.table
\END
\newsavebox{\myplot}
\savebox{\myplot}{%
\begin{tikzpicture}
\begin{axis}[grid=major]
\addplot+[smooth,
error bars/.cd,
y dir=both,
y explicit]
table[x index=0,
y index=1,
y error index=2]
{plots/mydata.table.digest};
\end{axis}
\end{tikzpicture}
}
\newcommand{\plotmyplot}{\usebox{\myplot}}
\begin{document}
stuff2 \plotmyplot
\end{document}
尝试概括
\newcommand{\prepareplot}[2]{
\bash[stdoutFile=#2.digest]
python error.py #2
\END
\expandafter\newsavebox\csname #1\endcsname
\expandafter\savebox\csname #1\endcsname{%
\begin{tikzpicture}
\begin{axis}[grid=major]
\addplot+[smooth,
error bars/.cd,
y dir=both,
y explicit]
table[x index=0,
y index=1,
y error index=2]
{#2.digest};
\end{axis}
\end{tikzpicture}}
\expandafter\newcommand\csname plot#1\endcsname\expandafter\usebox\csname #1\endcsname}
错误
! Use of \bashIII doesn't match its definition.
\prepareplot #1#2-> \bash [stdoutFile=#2.digest]
python error.py #2 \END \pa...
l.27 \prepareplot{myplotB}{plots/mydata.table}
?
! Emergency stop.
\prepareplot #1#2-> \bash [stdoutFile=#2.digest]
python error.py #2 \END \pa...
l.27 \prepareplot{myplotB}{plots/mydata.table}
! ==> Fatal error occurred, no output PDF file produced!
Transcript written on plots.log.
完整的 MWE(需要 Python 2.7 和error.py
)
\documentclass{article}
\usepackage{pgfplots,tikz,bashful}
\newcommand{\prepareplot}[2]{
\bash[stdoutFile=#2.digest]
python error.py #2 | \preparedplotname.digest
\END
\expandafter\newsavebox\csname #1\endcsname
\expandafter\savebox\csname #1\endcsname{%
\begin{tikzpicture}
\begin{axis}[grid=major]
\addplot+[smooth,
error bars/.cd,
y dir=both,
y explicit]
table[x index=0,
y index=1,
y error index=2]
{#2.digest};
\end{axis}
\end{tikzpicture}}
\expandafter\newcommand\csname plot#1\endcsname\expandafter\usebox\csname #1\endcsname}
\pgfplotsset{compat=1.7}
\prepareplot{myplotB}{plots/mydata.table}
\bash[stdoutFile=plots/mydata.table.digest]
python error.py plots/mydata.table
\END
\newsavebox{\myplot}
\savebox{\myplot}{%
\begin{tikzpicture}
\begin{axis}[grid=major]
\addplot+[smooth,
error bars/.cd,
y dir=both,
y explicit]
table[x index=0,
y index=1,
y error index=2]
{plots/mydata.table.digest};
\end{axis}
\end{tikzpicture}
}
\newcommand{\plotmyplot}{\usebox{\myplot}}
\begin{document}
stuff2 \plotmyplotB
\end{document}
答案1
该\bash
命令更改类别代码,以便附带多行脚本,因此不能在其他命令的参数中使用。
但是,对于单行代码来说,不需要 的全部功能\bash
,因此下面的代码应该可以工作:
\makeatletter
\newcommand{\rbash}[2][]{%
\begingroup
\setKeys@BL{#1}%
\begingroup\edef\x{\endgroup
\noexpand\bashIV{\detokenize{#2}}%
\noexpand\bashV{\detokenize{#2}}\logBL{bashV: Done!}%
}\x
\endgroup}
\makeatother
\rbash[stdoutFile=myls.digest]{ls -l 2>&1 > myls.digest}
我添加了一个命令只是为了测试它。
您的命令可能定义为
\newcommand{\prepareplot}[2]{%
\rbash[stdoutFile=#2.digest]{python error.py #2 | \preparedplotname.digest}
\expandafter\newsavebox\csname #1box\endcsname
\expandafter\sbox\csname #1box\endcsname{%
\begin{tikzpicture}
\begin{axis}[grid=major]
\addplot+[smooth,
error bars/.cd,
y dir=both,
y explicit]
table[x index=0,
y index=1,
y error index=2]
{#2.digest};
\end{axis}
\end{tikzpicture}}
\expandafter\newcommand\csname plot#1\endcsname{\expandafter\usebox\csname #1box\endcsname}}