Gnuplot绘制的堆叠和分组条形直方图

3
我想制作一个柱状图,像这个,即:多个组,每个组有许多条柱(在我的案例中为4条),每个柱子被分成几个部分(在我的案例中为两个部分)。
在我的案例中,我使用了四个算法来处理不同大小的向量(2^0到2^20)。每个算法都有两个“部分”,本地计算和通信。对于每个向量大小,我想显示每个算法执行本地计算和通信所需的时间,以及对应于这两个部分之和的总时间。
因此,我希望每个向量大小都有一组。在每个组中,有四个柱子对应于四个算法,每个柱子被分成一个(例如)红色部分对应于本地计算和一个蓝色部分对应于通信。
使用gnuplot可以实现吗?我可以提供任何有用的数据格式。
非常感谢您的帮助。

提供示例数据和脚本将有助于您获得答案。 :) 还请指出您的脚本中缺少什么以及您尝试了什么。 - Bernhard
当然。我在这里放了我的数据样本:http://pastebin.com/vtemLn98。由于我是一个绝对的初学者(我从Matlab转到gnuplot),我甚至不知道我想做的事情是否可行(例如,在Matlab中,除非你进行低级别编程或应用一些不寻常的技巧,否则是不可能的),所以我还没有开始写脚本。 - Spiros
1个回答

0

对于您的数据集,将本地和通讯部分堆叠起来是没有意义的,因为通讯部分太小了,在图表中看不清楚。无论如何,如果要结合堆叠和聚类,根据进一步的要求(图例条目、刻度标签等),这也会非常棘手。

以下是如何为您的数据集绘制聚类直方图的示例:

set style histogram clustered gap 1
set style data histogram
set style fill solid 1.0 noborder

set termoption enhanced

set xtics out nomirror

myxtic(x) = sprintf('2^{%d}', int(floor(log(x)/log(2) + 0.5)))
plot 'test.dat' using ($2+$3):xtic(myxtic(stringcolumn(1))) title 'Algorithm 1',\
     for [i=2:4] '' using (column(2*i)+column(2*i+1)) title sprintf('Algorithm %d', i)

结果是:

enter image description here

要使用分组算法,您可以使用newhistogram关键字创建新的分组:

set style histogram rowstacked title offset 4,1
set boxwidth 0.9 relative
set style fill solid 1.0 border lt -1
set xtics rotate by 90 right
plot newhistogram "Algorithm 1" lt 1,\
     'test.dat' using 2:xtic(1) title columnheader, \
     '' using 3 title columnheader,\
     newhistogram "Algorithm 2" lt 1,\
     'test.dat' using 4:xtic(1) notitle, \
     '' using 5 notitle,\
     newhistogram "Algorithm 3" lt 1,\
     'test.dat' using 6:xtic(1) notitle, \
     '' using 7 notitle,\
     newhistogram "Algorithm 4" lt 1,\
     'test.dat' using 8:xtic(1) notitle, \
     '' using 9 notitle

localcomm数据被堆叠在一起,但是comm部分非常小,在图表中几乎看不到(只有缩放后才能看到)。

输出使用了4.6.3版本和以下设置:

set terminal pngcairo size 1000,400
set output 'test.png'
set xtics font ',6'

结果是:

enter image description here

更复杂的x轴刻度显示需要一些技巧,因为对于直方图而言,x轴刻度不被视为数值,而是字符串。以下是一个示例:

set terminal pngcairo size 1000,400
set output 'test.png'

set style histogram rowstacked title offset 0,-0.5
set bmargin 3
set boxwidth 0.9 relative
set style fill solid 1.0 border lt -1
set termoption enhanced
set xtics out nomirror
myxtic(x) = (int(floor(log(x)/log(2) + 0.5)) % 5 == 0) ? sprintf('2^{%d}', int(floor(log(x)/log(2) + 0.5))) : ""

plot newhistogram "Algorithm 1" lt 1,\
     'test.dat' using 2:xtic(myxtic(real(stringcolumn(1)))) title columnheader, \
     '' using 3 title columnheader,\
     newhistogram "Algorithm 2" lt 1,\
     'test.dat' using 4:xtic(myxtic(real(stringcolumn(1)))) notitle, \
     '' using 5 notitle,\
     newhistogram "Algorithm 3" lt 1,\
     'test.dat' using 6:xtic(myxtic(real(stringcolumn(1)))) notitle, \
     '' using 7 notitle,\
     newhistogram "Algorithm 4" lt 1,\
     'test.dat' using 8:xtic(myxtic(real(stringcolumn(1)))) notitle, \
     '' using 9 notitle

有了结果

enter image description here


嗨,克里斯托夫。这看起来很不错,但我更喜欢能够更直接地比较这些算法的运行时间,即将不同算法的结果直接放在一起。换句话说,分组不应该根据算法进行,而应该根据大小进行。我从你的代码中学到了很多。你基本上创建了4个不同的直方图,并将它们放在一起。有没有办法将其放入循环中,以避免过多的编写? - Spiros
抱歉,我错过了实际要点 ;) 我更新了我的答案。在这种情况下,您需要一个聚类直方图。这不允许您堆叠本地和通信数据,但对于您提供的数据也没有意义。通信部分非常小,人们看不到它。将聚类与堆叠组合起来会变得非常棘手(尚未尝试)。 - Christoph
当你说提供的数据不适合这种图时,你是完全正确的。实际上,我忘记了我必须将每一列除以第一个算法的“comm”和“local”的总和。你以前的图看起来非常好,只是以一种使比较数据不那么方便的方式分组。使用plot的“for”选项生成多个直方图是不是有意义? - Spiros

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接