如何从表创建 pgfplots 循环列表?

如何从表创建 pgfplots 循环列表?

我知道可以使用 创建 pgfplots 循环列表\pgfplotscreateplotcyclelist。但是,pgfplots 手册中给出的示例明确列出了所有项目。我想知道是否可以通过循环遍历表(可能从文件加载)来创建循环列表。当有大量\addplot且每个都需要特殊样式时,这非常有用。有想法怎么做吗?谢谢。

答案1

Jake 的解决方案不起作用的原因是,在宏搜索分隔符\listmacro之前, 未展开。因此,整个宏被视为一个设置,而包含的 则作为设置的一部分展开,这会导致错误(设置中的换行符没有多大意义)。pgfplotscreateplotcyclelist\\\\

因此,为了使其工作,您必须\listmacro先手动扩展,然后将其提供给\pgfplotscreateplotcyclelist。有多种方法可以做到这一点。这里有一种方法,它使用 eTeX 的\unexpanded内部\edef来仅扩展\listmacro一次,否则会\\过早扩展并导致错误。我定义了一个新的宏\pgfplotscreateplotcyclelistfrommacro,它扩展了第二个参数,然后调用\pgfplotscreateplotcyclelist。请随意重命名它。

根据Jake的代码:

\documentclass{article}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{filecontents}

\newcommand*{\pgfplotscreateplotcyclelistfrommacro}[2]{%
    \begingroup
    % Expands the second argument once. The `\A` is only temporary used
    % and therefore in a group
    \edef\A{\noexpand\pgfplotscreateplotcyclelist{#1}{\unexpanded\expandafter{#2}}}%
    \expandafter
    \endgroup\A
}

\begin{filecontents}{cyclelist.txt}
green
pink
purple
\end{filecontents}
\pgfplotstableread{cyclelist.txt}{\cyclelist}

\begin{document}

\pgfplotstabletypeset[begin table={},end table={},skip coltypes,display columns/0/.style={string type},write to macro=\listmacro,typeset=false]\cyclelist

\begin{tikzpicture}
\pgfplotscreateplotcyclelistfrommacro{newcycle}{\listmacro}
\begin{axis}[cycle list name=newcycle]
\addplot {x^2};
\addplot {x^4};
\addplot {x^6};
\end{axis}
\end{tikzpicture}

\end{document}

答案2

我已经开始做某件事了,但还没成功。我把这个贴在这里,希望对 LaTeX 有更深理解的人能帮上忙。

以下代码用于pgfplotstable读取文件并将其保存在宏中,每行以 分隔\\,这是输入格式\pgfplotscreateplotcyclelist所期望的。但是,使用宏而不是正常的\\-分隔列表会失败,并显示

! 未定义控制序列。-
>\let \reserved@e
\relax \let \reserved@f \relax \@ifstar {\let \reserv...

我怀疑这与宏的扩展方式/是否扩展有关......

\documentclass{article}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{filecontents}

\begin{filecontents}{cyclelist.txt}
green
pink
\end{filecontents}
\pgfplotstableread{cyclelist.txt}{\cyclelist}

\begin{document}

\pgfplotstabletypeset[begin table={},end table={},skip coltypes,display columns/0/.style={string type},write to macro=\listmacro,typeset=false]\cyclelist
\show\listmacro % To show that the macro contents are what \pgfplotscreateplotcyclelist expects
\begin{tikzpicture}

\pgfplotscreateplotcyclelist{newcycle}{\listmacro}
%\pgfplotscreateplotcyclelist{newcycle}{green\\pink\\} % This works fine, as expected

\begin{axis}[cycle list name=newcycle]
\addplot {x^2};
\end{axis}
\end{tikzpicture}

\end{document}

答案3

我认为目前有几个挑战尚未解决:循环列表条目可以包含空格字符(这也是 pgfplots 的默认单元格分隔符)。此外,如果表格有多列,则可能需要选择特定列。

这里有一个解决这些问题的起点(尽管可能不是最优雅的界面):

\documentclass[a4paper]{article}
\usepackage{filecontents}

\begin{filecontents}{P.dat}
columnname
blue,mark=*
red,mark=square
dashed,mark=o
loosely dotted,mark=+
brown!60!black,mark options={fill=brown!40},mark=otimes*
\end{filecontents}
\usepackage{pgfplots}

\usepackage{pgfplotstable}


\makeatletter
% #1: table. The table should have either ONE column or the cols
% should be separate by semicolon (see the body of this macro)
% #2: column name
% #3: name of the target cycle list
% Example:
% \pgfplotscreateplotcyclelistfromtable{P.dat}{columnname}{my cycle list name}
\def\pgfplotscreateplotcyclelistfromtable#1#2#3{%
    \begingroup
    \gdef\pgfplots@tmp{}%
    \pgfplotstableread[col sep=semicolon]{#1}\table@tmp
    \pgfplotstableforeachcolumnelement{#2}\of\table@tmp\as\table@cell{%
        \begingroup
        \toks0=\expandafter{\table@cell}%
        \ifx\pgfplots@tmp\empty
            \xdef\pgfplots@tmp{{\the\toks0}}%
        \else
            \toks1=\expandafter{\pgfplots@tmp}%
            \xdef\pgfplots@tmp{\the\toks1,{\the\toks0}}%
        \fi
        \endgroup
    }%
    \toks0={\pgfplotscreateplotcyclelist{#3}}%
    \toks1=\expandafter{\pgfplots@tmp}%
    \xdef\pgfplots@tmp{\the\toks0{\the\toks1}}%
    \endgroup
    \show\pgfplots@tmp
    \pgfplots@tmp
}%
\makeatother
\pgfplotscreateplotcyclelistfromtable{P.dat}{[index]0}{mylist}

\begin{document}

\begin{tikzpicture}
    \begin{axis}[cycle list name=mylist]
        \addplot {x};
        \addplot {x-1};
        \addplot {x-2};
        \addplot {x-3};
        \addplot {x-4};
        \addplot {x-5};
    \end{axis}
\end{tikzpicture}

\end{document}

我想说它可以在每个 tex 发行版中运行(因为 \toks 和 \xdef 等是 tex 原语。)

答案4

对于那些对“更易于管理”的循环列表感兴趣的人,我在乳胶序言中定义了以下宏:

\def\setplotcycle{cycle list={%
{blue,mark=*},
{red,mark=square},
{green,mark=square}
}}

并在我的每个图中都包含 \setplotcycle。例如:

\begin{axis}[\setplotcycle]

现在我可以在一个地方更新所有图的颜色。希望这能有所帮助。

相关内容