foreach 循环内的 CSV groupplot 扩展

foreach 循环内的 CSV groupplot 扩展

我想从 CSV 文件中绘制多列的组图。CSV 文件如下所示:

a,b,x,y
1,2,3,4
5,6,8,1
9,2,4,5
5,5,1,9

因此我制作了一个包,使用下面的代码来绘制所有列(灵感来自http://www.traag.net/2015/01/12/plot-multiple-files-using-pgfplots/)。

这有效。但是,我想替换{a,b,y}主绘图循环中的fixed 语句

\pgfplotsforeachungrouped \y in {a,b,y}

比如

\pgfplotsforeachungrouped \y in \csvPlotYCol

其中\csvPlotYCol是作为命令调用选项传递的变量。因此,当我调用 CSV plot 命令时,我可以选择要绘制的列。

不幸的是,这不起作用。我很确定这是一个扩展问题,但我不知道如何解决它。我试过:

\noexpand\expandafter\addplot table\expandafter[x=\x, y=\y, col sep=comma] {#2};%

代替

\noexpand\addplot table[x=\x, y=\y, col sep=comma] {#2};%

但没有成功。

我很高兴听到你的想法。


完整的可编译代码如下。这是main.tex文件:

\documentclass{article}
\usepackage{csvplot}

  \pgfplotsset{style1/.style=%
    {%
    height = .5\textwidth,%
    width = .5\textwidth,%
    grid = both,%
    }%
  }%

\begin{document}

    \csvPlotXY[%
        style = style1,%
        align = force,%
        caption = This is a caption,%
        label = mark1,%
        xCol = {x},%
        yCol = {a,b,y},%
    ] {data.csv}

    In \autoref{mark1} you see lines.

\end{document}

这是我写的完整包:你需要调用它csvplot.sty

\NeedsTeXFormat{LaTeX2e}%
\ProvidesPackage{csvplot}[2017/05/17 CSV Plot]%

\RequirePackage{etoolbox}%
\RequirePackage{pgfplots}%
\RequirePackage{tikz}%
\RequirePackage{pgfkeys}%
\RequirePackage{float}%
\RequirePackage{hyperref}%

\pgfplotsset{compat=newest}%
\usepgfplotslibrary{groupplots}%

\DeclareOption{default}{%
\pgfplotsset{csvPlotStyle/.style=%
    {%
    grid=both,%
    }%
}%
}%

\ExecuteOptions{default}%
\ProcessOptions\relax%

% Set up the keys
\pgfkeys{
    % Switch to /csvPlotXY key subset
    /csvPlotXY/.is family, /csvPlotXY,%
    % User options
    %% default options
    default/.style = {width = \textwidth , height = .5\textwidth, xCol = x, yCol = y, style = csvPlotStyle, align = top},%
    %% definitions
    width/.estore in = \csvPlotWidth,%
    height/.estore in = \csvPlotHeight,%
    xCol/.estore in = \csvPlotXCol,%
    yCol/.estore in = \csvPlotYCol,%
    style/.estore in = \csvPlotStyle,%
    caption/.estore in = \csvPlotCaption,%
    label/.estore in = \csvPlotLabel,%
    align/.style = {alignments/#1/.get = \csvPlotAlignment},%
    % dictionary for alignment of figure
    alignments/.cd,%
        top/.initial = t,%
        here/.initial = h,%
        bottom/.initial = b,%
        force/.initial = H,%
        page/.initial = p,%
}

\newcommand{\csvPlotXY}[2][]{%
    \pgfkeys{/csvPlotXY, default, #1}%
    % Expand figure options
    \def\efigure{\begin{figure}}\expandafter\efigure\expandafter[\csvPlotAlignment]%
        \centering
    \begin{tikzpicture}%
        \begin{groupplot} [
            width=\csvPlotWidth,%
            height=\csvPlotHeight,%
            % Plot loop: All x/y columns for multiple plots in one axis
            \csvPlotStyle,%
            ]%
            \pgfplotsforeachungrouped \x in {x} {%
                \pgfplotsforeachungrouped \y in {a,b,y} {%
                    \eappto\PlotList{%
                        \noexpand\nextgroupplot%
                        \noexpand\addplot table[x=\x, y=\y, col sep=comma] {#2};%
                        \noexpand\addlegendentry{\y}%
                    }%
                }%
            }%
            \PlotList%
        \end{groupplot}%
    \end{tikzpicture}%
        \caption{\csvPlotCaption}%
        \label{\csvPlotLabel}%
    \end{figure}
}%

这是输入数据data.csv

a,b,x,y
1,2,3,4
5,6,8,1
9,2,4,5
5,5,1,9

目前,a、b 和 y 列始终被绘制,以便编译工作。

结果如下: 编译结果

答案1

关键是修改样式文件以利用键,因为您承认它已硬连线到a,b,y与 进行绘图x。然而,诀窍在于,必须扩展包含xColyCol键(即\csvPlotXCol\csvPlotYCol)的宏才能被 消化\pgfplotsforeachungrouped。修改后的宏是

\newcommand{\csvPlotXY}[2][]{%
    \pgfkeys{/csvPlotXY, default, #1}%
    % Expand figure options
    \def\efigure{\begin{figure}}\expandafter\efigure\expandafter[\csvPlotAlignment]%
        \centering
    \begin{tikzpicture}%
        \begin{groupplot} [
            width=\csvPlotWidth,%
            height=\csvPlotHeight,%
            % Plot loop: All x/y columns for multiple plots in one axis
            \csvPlotStyle,%
            ]%
            \def\tmpX{\pgfplotsforeachungrouped \x in }%
            \def\tmpY{\pgfplotsforeachungrouped \y in }%
            \expandafter\tmpX\expandafter{\csvPlotXCol} {%
                \expandafter\tmpY\expandafter {\csvPlotYCol} {%
                    \eappto\PlotList{%
                        \noexpand\nextgroupplot%
                        \noexpand\addplot table[x=\x, y=\y, col sep=comma] {#2};%
                        \noexpand\addlegendentry{\y}%
                    }%
                }%
            }%
            \PlotList%
        \end{groupplot}%
    \end{tikzpicture}%
        \caption{\csvPlotCaption}%
        \label{\csvPlotLabel}%
    \end{figure}
}%

MWE。在第一个图中,它是a,b,yx;在第二个图中,它是b,yx;在第三个图中,它是b,ya

\documentclass{article}
\usepackage{csvplot}

  \pgfplotsset{style1/.style=%
    {%
    height = .5\textwidth,%
    width = .5\textwidth,%
    grid = both,%
    }%
  }%

\begin{document}
    \csvPlotXY[%
        style = style1,%
        align = force,%
        caption = This is a caption,%
        label = mark1,%
        xCol = {x},%
        yCol = {a,b,y},%
        caption = {plotted against ``x''},
    ] {data.csv}

    \csvPlotXY[%
        style = style1,%
        align = force,%
        caption = This is a caption,%
        label = mark1,%
        xCol = {x},%
        yCol = {b,y},%
        caption = {plotted against ``x''},
    ] {data.csv}

    \csvPlotXY[%
        style = style1,%
        align = force,%
        caption = This is a caption,%
        label = mark1,%
        xCol = {a},%
        yCol = {b,y},%
        caption = {plotted against ``a''},
    ] {data.csv}
\end{document}

样式csvplot.sty文件,包括修改后的\csvPlotXY宏:

\NeedsTeXFormat{LaTeX2e}%
\ProvidesPackage{csvplot}[2017/05/17 CSV Plot]%

\RequirePackage{etoolbox}%
\RequirePackage{pgfplots}%
\RequirePackage{tikz}%
\RequirePackage{pgfkeys}%
\RequirePackage{float}%
\RequirePackage{hyperref}%

\pgfplotsset{compat=newest}%
\usepgfplotslibrary{groupplots}%

\DeclareOption{default}{%
\pgfplotsset{csvPlotStyle/.style=%
    {%
    grid=both,%
    }%
}%
}%

\ExecuteOptions{default}%
\ProcessOptions\relax%

% Set up the keys
\pgfkeys{
    % Switch to /csvPlotXY key subset
    /csvPlotXY/.is family, /csvPlotXY,%
    % User options
    %% default options
    default/.style = {width = \textwidth , height = .5\textwidth, xCol = x, yCol = y, style = csvPlotStyle, align = top},%
    %% definitions
    width/.estore in = \csvPlotWidth,%
    height/.estore in = \csvPlotHeight,%
    xCol/.estore in = \csvPlotXCol,%
    yCol/.estore in = \csvPlotYCol,%
    style/.estore in = \csvPlotStyle,%
    caption/.estore in = \csvPlotCaption,%
    label/.estore in = \csvPlotLabel,%
    align/.style = {alignments/#1/.get = \csvPlotAlignment},%
    % dictionary for alignment of figure
    alignments/.cd,%
        top/.initial = t,%
        here/.initial = h,%
        bottom/.initial = b,%
        force/.initial = H,%
        page/.initial = p,%
}

\newcommand{\csvPlotXY}[2][]{%
    \pgfkeys{/csvPlotXY, default, #1}%
    % Expand figure options
    \def\efigure{\begin{figure}}\expandafter\efigure\expandafter[\csvPlotAlignment]%
        \centering
    \begin{tikzpicture}%
        \begin{groupplot} [
            width=\csvPlotWidth,%
            height=\csvPlotHeight,%
            % Plot loop: All x/y columns for multiple plots in one axis
            \csvPlotStyle,%
            ]%
            \def\tmpX{\pgfplotsforeachungrouped \x in }%
            \def\tmpY{\pgfplotsforeachungrouped \y in }%
            \expandafter\tmpX\expandafter{\csvPlotXCol} {%
                \expandafter\tmpY\expandafter {\csvPlotYCol} {%
                    \eappto\PlotList{%
                        \noexpand\nextgroupplot%
                        \noexpand\addplot table[x=\x, y=\y, col sep=comma] {#2};%
                        \noexpand\addlegendentry{\y}%
                    }%
                }%
            }%
            \PlotList%
        \end{groupplot}%
    \end{tikzpicture}%
        \caption{\csvPlotCaption}%
        \label{\csvPlotLabel}%
    \end{figure}
}%
\endinput

输出:

在此处输入图片描述

答案2

我找到了一个解决方案,即在 中找到以下宏扩展csvplot.sty。它可能与上面的答案完全相同,即在使用前扩展宏。但是,这是通过不同的命令完成的。

\newcommand{\csvPlotXY}[2][]{%
    \pgfkeys{\csvPlotXY, default, #1}%
    % Expand figure options
    \def\efigure{\begin{figure}}\expandafter\efigure\expandafter[\csvPlotAlignment]%
        \centering
    \begin{tikzpicture}%
        \begin{groupplot} [
            width=\csvPlotWidth,%
            height=\csvPlotHeight,%
            % Plot loop: All x/y columns for multiple plots in one axis
            \csvPlotStyle,%
            ]%
            \edef\XIterate{%
                \noexpand\pgfplotsforeachungrouped \noexpand\x in {\csvPlotXCol}
            }
            \edef\YIterate{%
                \noexpand\pgfplotsforeachungrouped \noexpand\y in {\csvPlotYCol}
            }
            \XIterate {%
                \YIterate {%
                    \eappto\PlotList{%
                        \noexpand\nextgroupplot%
                        \noexpand\addplot table[x=\x, y=\y, col sep=comma] {#2};%
                        \noexpand\addlegendentry{\y}%
                    }%
                }%
            }%
            \PlotList%
        \end{groupplot}%
    \end{tikzpicture}%
        \caption{\csvPlotCaption}%
        \label{\csvPlotLabel}%
    \end{figure}
}%

特别是临时宏的定义

\edef\XIterate{%
    \noexpand\pgfplotsforeachungrouped \noexpand\x in {\csvPlotXCol}
}

然后调用\XIterate

相关内容