読み取ってプロットしたい表がいくつかありますが、それぞれに独自のスタイルがあります。便宜上、同じタグを使用するのが好きです。以下は MWE です。
\documentclass{minimal}
\usepackage{pgfplotstable}
\begin{filecontents}{tabA.dat}
x y
0 0
1 1
2 2
3 3
\end{filecontents}
\begin{filecontents}{tabB.dat}
x y
0 1
1 2
2 3
3 4
\end{filecontents}
\pgfplotsset{compat=newest,
tabA/.style={color=red,mark=*},
tabB/.style={color=black,mark=o},
}
\pgfplotstableread{tabA.dat}\tabA
\pgfplotstableread{tabB.dat}\tabB
\begin{document}
\begin{tikzpicture}
\begin{axis}[legend,legend pos=south east]
\addplot[tabA] table[x=x,y=y] {\tabA};\label{pgf:tabA}\addlegendentry{tabA}
\addplot[tabB] table[x=x,y=y] {\tabB};\label{pgf:tabB}\addlegendentry{tabB}
\end{axis}
\end{tikzpicture}
\end{document}
\pgfplotsforeachinvoke
または を使って同じ結果を得ることができますか\foreach
?
\begin{tikzpicture}
\begin{axis}[legend,legend pos=south east]
\pgfplotsinvokeforeach{tabA,tabB}{%
% The following doesn't work, of course
\addplot[#1] table[x=x,y=y] {\#1}; % <- Magic goes here
}
\end{axis}
\end{tikzpicture}
もちろん、この単純なケースでは、
\addplot[#1] table[x=x,y=y] {#1.dat};
しかし、ファイル名がパターンに従っていない場合や、テーブルを読み取って保存し、それを変更したり、何度も再利用したりしたい場合もあります。
答え1
TeX.SE へようこそ! 常に可能なことが 1 つあります。
トークン リストを希望どおりに組み立てるマクロを記述する (ここでは、
\addplot
適切なオプションを使用して一連のコマンドを連結します)。\foreachTable
次に、のような出力を出力する2 番目のマクロ (私のコードでは、 の 2 番目の引数から構築されています) を使用します。ここで、 は\begin{axis}[...]#1\end{axis}
、#1
すべてのコマンドを含む以前に組み立てられたトークン リストに置き換えられます\addplot
。
この技術常に機能する(2 番目のマクロが展開されると、TeX 入力ストリームは、すべてのコードを手動で入力した場合とまったく同じ状態になります)。したがって、これを使用して、表、画像など、必要なものをプログラムで生成できます。
完全なコード:
\begin{filecontents}{tabA.dat}
x y
0 0
1 1
2 2
3 3
\end{filecontents}
\begin{filecontents}{tabB.dat}
x y
0 1
1 2
2 3
3 4
\end{filecontents}
\documentclass[tikz, border=2mm]{standalone}
\usepackage{xparse}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\ExplSyntaxOn
\seq_new:N \l__millo_plot_cmds_tl
\cs_new_protected:Npn \millo_foreach_table_do_axis:nNn #1#2#3
{
\tl_clear:N \l__millo_plot_cmds_tl
\clist_map_inline:nn {#1}
{
\tl_set:Nn \l_tmpa_tl {#3}
\regex_replace_all:nnN { \c{myTable} } { \c{##1} } \l_tmpa_tl
\tl_put_right:NV \l__millo_plot_cmds_tl \l_tmpa_tl
}
\exp_args:No #2 \l__millo_plot_cmds_tl
}
\NewDocumentCommand \foreachTable { m m m }
{
\cs_set_protected:Npn \__millo_axis_func:n ##1 {#2}
\millo_foreach_table_do_axis:nNn {#1} \__millo_axis_func:n {#3}
}
\ExplSyntaxOff
\pgfplotsset{
tabA/.style={color=red,mark=*},
tabB/.style={color=black,mark=o},
}
\pgfplotstableread{tabA.dat}\tabA
\pgfplotstableread{tabB.dat}\tabB
\begin{document}
\begin{tikzpicture}
\foreachTable{tabA, tabB}
{
\begin{axis}[legend, legend pos=south east]
#1
\end{axis}
}
{ \addplot[#1] table[x=x,y=y] {\myTable}; \addlegendentry{#1} }
\end{tikzpicture}
\end{document}
通話の説明:
\foreachTable{tabA, tabB}
{
\begin{axis}[legend, legend pos=south east]
#1
\end{axis}
}
{ \addplot[#1] table[x=x,y=y] {\myTable}; \addlegendentry{#1} }
最初の引数はエントリのリストです (各エントリは 1 つの\addplot
コマンドにつながります)。
#1
2 番目の引数は、内部が自動的に生成されたコマンドによって置き換えられた後に挿入されるものです\addplot
。
3 番目の引数は、便利な置換を使用して、自動的に生成される各プロットのコードを指定します。
#1
エントリ名に置き換えられます(ここではtabA
thentabB
)。\myTable
エントリ名から構築された制御シーケンス トークンに置き換えられます (ここでは、\tabA
最初のエントリの場合は 、\tabB
2 番目のエントリの場合は )。
手動でさらにプロットを追加したい場合(ここでは、自動生成されたプロットの前後に 1 つずつ)、たとえば次のようにします。
\foreachTable{tabA, tabB}
{
\begin{axis}[legend, legend pos=south east]
\addplot {sin(deg(\x))}; \addlegendentry{$\sin$}
#1
\addplot {sqrt(\x)}; \addlegendentry{$x\mapsto \sqrt{x}$}
\end{axis}
}
{ \addplot[#1] table[x=x,y=y] {\myTable}; \addlegendentry{#1} }
持っていない人のために\regex_replace_all:nnN
がl3kernel
古すぎて を取得できない場合は\regex_replace_all:nnN
、次のことができます。
\cs_generate_variant:Nn \tl_replace_all:Nnn { Nno }
の前に追加します\cs_new_protected:Npn \millo_foreach_table_do_axis:nNn #1#2#3
。行を置き換える
\regex_replace_all:nnN { \c{myTable} } { \c{##1} } \l_tmpa_tl
と
\exp_args:NNno \tl_replace_all:Nno \l_tmpa_tl { \myTable } { \use:c {##1} }
そうすればうまくいくはずだ条件で括弧内では使用しないでください\myTable
。たとえば、
\foreachTable{tabA, tabB}
{
...
}
{ \addplot[#1] table[x=x,y=y] \myTable; \addlegendentry{#1} }
の代わりに:
\foreachTable{tabA, tabB}
{
...
}
{ \addplot[#1] table[x=x,y=y] {\myTable}; \addlegendentry{#1} }