我想从 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
。然而,诀窍在于,必须扩展包含xCol
和yCol
键(即\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,y
与x
;在第二个图中,它是b,y
与x
;在第三个图中,它是b,y
与a
。
\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