在下面的代码中,通过显式添加Proc1
和Proc2
列来创建额外的列。当存在两列以上时,如何在循环中进行此添加?
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.3}
\pgfplotstableread[col sep=comma]{
Function,Proc1,Proc2
Add,1,2
Sub,3,4
Div,2,3
}{\data}
% sort the table
\pgfplotstablesort[
create on use/sum/.style={
create col/expr={
\thisrow{Proc1} + \thisrow{Proc2}
},
},
sort cmp=float >,
sort key=sum,
]{\dataSorted}{\data}
答案1
我认为你不需要循环。
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.3}
\pgfplotstableread[col sep=comma]{
Function,Proc1,Proc2,Proc3
Add,1,2,3
Sub,3,4,4
Div,2,3,5
}{\data}
% sort the table
\pgfplotstablesort[
create on use/sum/.style={
create col/expr={
\thisrow{Proc1} + \thisrow{Proc2} + \thisrow{Proc3}
},
},
sort cmp=float >,
sort key=sum,
]{\dataSorted}{\data}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
cycle list=Dark2,
ybar stacked,
ymin=0,
xtick=data,
xtick pos=left,
ytick pos=left,
axis lines=left,
xticklabels from table={\dataSorted}{Function},
x tick label style={rotate=45, anchor=north east, inner sep=0mm},
ylabel=Elapsed seconds,
xlabel=Function,
legend pos=outer north east,
legend style={draw=none},
enlarge x limits=0.1,
]
\pgfplotstablegetcolsof{\dataSorted}
\pgfmathtruncatemacro\numberofcols{\pgfplotsretval-1}
\foreach \i in {1,...,\numberofcols} {
\addplot table [y index=\i, x expr=\coordindex] {\dataSorted};
}
\end{axis}
\end{tikzpicture}
\end{document}
我的答案的下半部分引用自这个答案。
您还可以使用
\pgfplotstablesort[
create on use/sum/.style={
create col/expr={
\thisrowno{1} + \thisrowno{2} + \thisrowno{3}
},
},
sort cmp=float >,
sort key=sum,
]{\dataSorted}{\data}
答案2
这可以通过一些“TeX hackery”来实现。这里有一个解决方案,将所有列索引大于 0 的列相加并排序。
% used PGFPlots v1.16
\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.3}
% added columns `Proc3' and `Proc4'
\pgfplotstableread[col sep=comma]{
Function,Proc1,Proc2,Proc3,Proc4
Add,1,2,3,4
Sub,3,4,2,5
Div,2,3,1,2
}{\data}
\pgfplotstableset{
% ---------------------------------------------------------------------
% (provided by Christian Feuersänger)
create on use/sum/.code={
\let\expr=\empty
% sum all selected row values:
\pgfplotstableforeachcolumn\data\as{\X}{%
\ifnum\pgfplotstablecol>0 % skip the first column
\ifx\expr\empty
\edef\expr{\noexpand\thisrow{\X}}%
\else
\toks0=\expandafter{\expr}%
\edef\expr{\the\toks0 + \noexpand\thisrow{\X}}%
\fi
\fi
}%
\message{Using expr=\meaning\expr^^J}%
\pgfkeysalso{/pgfplots/table/create col/expr=\expr}%
},
% ---------------------------------------------------------------------
}
% sort the table
\pgfplotstablesort[
% ... which we then use to sort the table
sort key=sum,
% the sorted table is then stored in `\dataSorted', which of course then
% has to be used everywhere in the `axis' environment
]{\dataSorted}{\data}
\begin{document}
% \pgfplotstabletypeset[string type]\dataSorted
\begin{tikzpicture}
\begin{axis}[
ybar stacked,
ymin=0,
ylabel=Elapsed seconds,
xlabel=Function,
xtick=data,
axis lines=left,
xticklabels from table={\dataSorted}{Function},
x tick label style={rotate=45, anchor=north east, inner sep=0mm},
xtick pos=left,
ytick pos=left,
enlarge x limits=0.1,
]
\pgfplotstablegetcolsof{\dataSorted}
\pgfmathtruncatemacro\numberofcols{\pgfplotsretval-1}
\foreach \i in {1,...,\numberofcols} {
\addplot table [x expr=\coordindex,y index=\i] {\dataSorted};
}
\end{axis}
\end{tikzpicture}
\end{document}