我已经在想要达到的目标上取得了很大进展,但仍有一些需要改进的地方。我现在拥有的图像如下:
但是,我们可以看到,这些百分比都是相对于 Ref 的,Ref 为 100%。查看第二条(x 轴 4),我们有 64.2+1.6+20.6 = 86.4 != 100。除此之外,最好所有堆栈的总时间都显示在它上面。我的想法粗略概括如下:
文件数据.txt:
one,two,three,four
Ref,0.0,194.228732386,0.0
4,40.0069652252,3.1391023845,124.752030532
8,31.416268219,4.0078951455,111.883188346
9,76.8558069667,3.9906615645,112.515372569
11,82.992369082,4.38474317025,112.11896845
13,81.5133020117,4.27987078675,116.598416893
16,81.5851874813,8.44496483425,117.332427258
Latex 文件:
\pgfplotstableread[col sep = comma]{data.txt}\mydata
\makeatletter
% To allow the 'Ref' x-axis entry
\pgfplotsset{
/pgfplots/flexible xticklabels from table/.code n args={3}{%
\pgfplotstableread[#3]{#1}\coordinate@table
\pgfplotstablegetcolumn{#2}\of{\coordinate@table}\to\pgfplots@xticklabels
\let\pgfplots@xticklabel=\pgfplots@user@ticklabel@list@x
}
}
% For calculating the percentage
\pgfplotsset{
compat=1.5.1,
percentage ticks/.code={
\pgfplotsset{
xtick pos=left,
axis x line*=left,
xlabel=Units,
nodes near coords={
\pgfkeys{
/pgf/fpu=true, % PGFplots uses floating points internally
/pgf/fpu/output format=fixed
}
\pgfmathparse{100*\pgfplotspointmeta/\pgfplots@axiswide@metamax}
\pgfmathprintnumber{\pgfmathresult}\,\%
},
every node near coord/.append style={yshift=1ex}
}
}
}
\makeatother
\begin{tikzpicture}
\begin{axis}[
/pgf/number format/precision=1,
compat=newest, %Better label placement
ybar stacked,
width=1.2\textwidth,
height=0.4\textheight,
enlarge y limits={upper, value=0.2},
ymin=0,
enlarge x limits = 0.2,
bar width=32pt,
title={Instance els19 with 1\% max error},
legend style={at={(0.5,-0.15)},
anchor=north,legend columns=0},
ylabel={Time in milisseconds},
xtick=data,
flexible xticklabels from table={data.txt}{one}{col sep=comma},
xticklabel style={text height=1.5ex},
nodes near coords,
axis lines*=left,
cycle list={
{fill=black!30,draw=black!30},
{fill=black!20,draw=black!20},
{fill=black!10,draw=black!10}
},
axis on top,
major grid style=white,
ymajorgrids,
legend style={draw=none,/tikz/every even column/.append style={column sep=0.5cm}},
percentage ticks
]
\addplot table[x expr=\coordindex, y=two]{\mydata};
\addplot table[x expr=\coordindex, y=three]{\mydata};
\addplot table[x expr=\coordindex, y=four]{\mydata};
\legend{Best 1\%,Average 1\%,Worst 1\%}
\end{axis}
\end{tikzpicture}
我觉得最有趣的一行是:
\pgfmathparse{100*\pgfplotspointmeta/\pgfplots@axiswide@metamax}
但是,我查阅手册很长时间也无法找到适合“当前”栏的宏。
任何帮助/指点都将不胜感激!
答案1
由于人们对此表示赞同,我想我应该用我的解决方案来回应:
我用总和扩展了数据字段,这在我的例子中是可行的。我相信您也可以通过使用 \pgfplotstable 创建临时表来做到这一点。
% Showing the sum on top
\pgfplotsset{
show sum on top/.style={
/pgfplots/scatter/@post marker code/.append code={%
\pgfkeys{
/pgf/fpu=true, % PGFplots uses floating points internally
/pgf/fpu/output format=fixed
}
\pgfmathparse{\pgfkeysvalueof{/data point/x}}
\pgfmathtruncatemacro\xidx{\pgfmathresult}
\pgfplotstablegetelem{\xidx}{sum}\of{\mydata}
\let\yval\pgfplotsretval
\node[
at={(normalized axis cs:%
\pgfkeysvalueof{/data point/x},%
\yval)%
},
anchor=south,
]
{
\pgfmathprintnumber{\yval}
};
},
},
}
\pgfplotsset{
percentage ticks/.code={
\pgfplotsset{
nodes near coords={
\pgfkeys{
/pgf/fpu=true, % PGFplots uses floating points internally
/pgf/fpu/output format=fixed
%/pgf/number format/.cd,fixed,fixed zerofill, precision=2
}
\pgfmathparse{\pgfkeysvalueof{/data point/x}}
\pgfmathtruncatemacro\xidx{\pgfmathresult}
\pgfplotstablegetelem{\xidx}{sum}\of{\mydata}
\pgfmathparse{100*\pgfplotspointmeta/\pgfplotsretval}
\let\percent\pgfmathresult
\ifthenelse{\lengthtest{\percent pt=100 pt}}{
\pgfmathprintnumber[fixed,fixed zerofill, precision=0]{\percent}\%
}{
\ifthenelse{\lengthtest{\percent pt<10 pt}}{
\pgfmathprintnumber[fixed,fixed zerofill, precision=2]{\percent}\%
}{
\pgfmathprintnumber[fixed,fixed zerofill, precision=1]{\percent}\%
}
}
},
every node near coord/.append style={yshift=1.2ex,xshift=-1.7ex,font=\footnotesize} %anchor=west,xshift=-7.2ex}
}
}
}
\begin{axis} [
xtick=data,
flexible xticklabels from table={data.txt}{gran}{col sep=comma},
xticklabel style={text height=1.5ex},
nodes near coords,
percentage ticks
]
\addplot table[x expr=\coordindex, y=two]{\mydata};
\addplot [show sum on top] table[x expr=\coordindex, y=three]{\mydata}; % Note that "show sum on top" should be applied to the plot which always is different from 0
\addplot table[x expr=\coordindex, y=four]{\mydata};
\legend{Prefetch, Execute, Optimized}
\end{axis}
恐怕这不是一个非常简单的工作示例,但它展示了以下想法:
通过获取 x 索引来计算百分比,然后使用该索引在表中查找总和,然后将节点的 y 值除以总和。
在条形图顶部添加总和有点类似。对于每个 x 轴上的一个项目(我选择“two”图,因为该图始终具有非零值),您只需创建一个具有(x=x,y=总和值)坐标的节点。显然零值会被忽略,我不确定如何处理。同样值得注意的是,我只修改了片段,因为它们最初来自 tex SE 上的其他线程。