众所周知这个答案,可以使用discard if not
style/filter 从表中过滤行。但此解决方案仅在提供文件名作为 的参数时才有效,如果使用 读取表并将其用作参数,则\addplot table
它将不起作用:\pgfplotstableread{file}\name
\addplot[discard if not...] table \name;
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage{pgfplotstable}
\usepackage{filecontents}
\begin{filecontents}{fulltable.dat}
houses instance value
20 1 8919
20 2 8965
20 3 8901
20 4 8816
20 5 8875
20 6 9027
20 7 8915
20 8 8907
20 9 8832
20 10 8934
200 1 84714
200 3 85630
200 4 84748
200 5 84565
200 6 85109
200 7 84588
200 8 84638
200 9 84673
200 10 85170
\end{filecontents}
\begin{document}
\pgfplotsset{
discard if not/.style 2 args={
x filter/.code={
\edef\tempa{\thisrow{#1}}
\edef\tempb{#2}
\ifx\tempa\tempb
\else
\def\pgfmathresult{inf}
\fi
}
}
}
\pgfplotstableread{fulltable.dat}\fulltable
\begin{tikzpicture}[trim axis left]
\begin{axis}[
title={{\bfseries Plot for 20 houses instances}},
xlabel={Instance},
ylabel={Value}]
\addplot+[only marks, discard if not={houses}{20}] table[x=instance, y=value]
{fulltable.dat};
\end{axis}
\end{tikzpicture}
\begin{tikzpicture}[trim axis left]
\begin{axis}[
title={{\bfseries Plot for 20 houses instances}},
xlabel={Instance},
ylabel={Value}]
\addplot+[only marks, discard if not={houses}{20}] table[x=instance, y=value]
{\fulltable};
\end{axis}
\end{tikzpicture}
\end{document}
该怎么办?我希望这个东西能用于宏。
答案1
总结
以下工作
\def\thisrowunavailableloadtabledirectly{thisrow_unavailable_load_table_directly}
\def\sudogetthisrow#1#2{
\edef#2{\thisrow{#1}}
\ifx#2\thisrowunavailableloadtabledirectly % if \thisrow fails to get the element
% then #2 is thisrow_unavailable_load_table_directlye
% we have a backup
\getthisrow{#1}{}
\let#2=\pgfplotsretval
\fi
}
\pgfplotsset{
discard if not/.style 2 args={
x filter/.code={
\sudogetthisrow{#1}\tempa
\edef\tempb{#2}
\ifnum\tempa=\tempb
\else
\def\pgfmathresult{inf}
\fi
\message{^^J\tempa,\tempb,\pgfmathresult^^J}
}
}
}
故事
当从宏读取表格时,pgfplots 将执行宏\pgfplots@addplotimpl@table@fromstructure@
。在这种情况下\thisrow
,和\thisrowno
不起作用。因此,pgfplotscoordprocessing.code.tex
作者在 6522-6529 行添加了一些注释
% These macros are-unfortunately- not accessable here. And the % worst is: error messages are impossible either because they are % not executed... try to provide useful hints: \def\thisrow##1{thisrow_unavailable_load_table_directly}% \def\thisrowno##1{thisrowno_unavailable_load_table_directly}% % this should work. \def\getthisrow##1##2{\pgfplotstablegetelem{\coordindex}{##1}\of{#3}{##2}}% \def\getthisrowno##1##2{\pgfplotstablegetelem{\coordindex}{[index]##1}\of{#3}{##2}}% %
看起来作者建议我们应该使用\getthisrow{houses}\tempa
。
但是如果你尝试这样做,你会得到另一个错误。原因是\pgfplotstablegetelem
只接受三个参数。因此{##2}
(将是\tempa
)将被留在外面,并且不可避免地会发出undefined control sequence
。
所以这里的技巧是定义一个须藤getthisrow 版本
- 尝试通过以下方式获取元素
\edef\tempa{\thisrow{houses}}
- 如果失败,请尝试
\getthisrow{houses}{}
(注意空参数)\pgfplotstablegetelem
将存储元素到\pgfplotsretval
- 放手
tempa
\pgfplotsretval
完整工作代码
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}
\usepackage{pgfplotstable}
\usepackage{filecontents}
\begin{filecontents}{fulltable.dat}
houses instance value
20 1 8919
20 2 8965
20 3 8901
20 4 8816
20 5 8875
20 6 9027
20 7 8915
20 8 8907
20 9 8832
20 10 8934
200 1 84714
200 3 85630
200 4 84748
200 5 84565
200 6 85109
200 7 84588
200 8 84638
200 9 84673
200 10 85170
\end{filecontents}
\begin{document}
\def\thisrowunavailableloadtabledirectly{thisrow_unavailable_load_table_directly}
\def\sudogetthisrow#1#2{
\edef#2{\thisrow{#1}}
\ifx#2\thisrowunavailableloadtabledirectly % if \thisrow fails to get the element
% then #2 is thisrow_unavailable_load_table_directlye
% we have a backup
\getthisrow{#1}{}
\let#2=\pgfplotsretval
\fi
}
\pgfplotsset{
discard if not/.style 2 args={
x filter/.code={
\sudogetthisrow{#1}\tempa
\edef\tempb{#2}
\ifnum\tempa=\tempb
\else
\def\pgfmathresult{inf}
\fi
\message{^^J\tempa,\tempb,\pgfmathresult^^J}
}
}
}
\pgfplotstableread{fulltable.dat}\fulltable
\begin{tikzpicture}[trim axis left]
\begin{axis}[
title={{\bfseries Plot for 20 houses instances}},
xlabel={Instance},
ylabel={Value}]
\addplot+[only marks, discard if not={houses}{20}] table[x=instance, y=value]
{fulltable.dat};
\end{axis}
\end{tikzpicture}
\begin{tikzpicture}[trim axis left]
\begin{axis}[
title={{\bfseries Plot for 20 houses instances}},
xlabel={Instance},
ylabel={Value}]
\addplot+[only marks, discard if not={houses}{20}] table[x=instance, y=value]
{\fulltable};
\end{axis}
\end{tikzpicture}
\end{document}