我知道可以使用 创建 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]
现在我可以在一个地方更新所有图的颜色。希望这能有所帮助。