Gnuplot直方图簇状图(条形图)每个类别一行

20

直方图聚类 / 条形图

我正试图使用 gnuplot 根据数据文件生成以下直方图聚类,其中每个类别在数据文件中表示为单独的一行,每年一个:

# datafile
year   category        num_of_events
2011   "Category 1"    213
2011   "Category 2"    240
2011   "Category 3"    220
2012   "Category 1"    222
2012   "Category 2"    238
...

期望的直方图聚类

但我不知道如何按每个类别一行的方式做到这一点。如果有人知道如何使用gnuplot实现这一点,我会很高兴。

堆叠直方图聚类/堆叠柱状图

更好的是像下面的堆叠直方图聚类,其中堆叠的子类别由数据文件中的单独列表示:

# datafile
year   category        num_of_events_for_A    num_of_events_for_B
2011   "Category 1"    213                    30
2011   "Category 2"    240                    28
2011   "Category 3"    220                    25
2012   "Category 1"    222                    13
2012   "Category 2"    238                    42
...

期望的堆叠直方图簇

非常感谢您的提前帮助!


这些其实只是垂直条形图。除非我有一个项目数组并且代码必须对其进行分组和计数,否则我不会称之为直方图。 - Paul
可能相关:https://dev59.com/DnRC5IYBdhLWcg3wVvnL请仅返回翻译后的文本。 - Paul
谢谢 @Paul,我已相应地修改了标题。 - fiedl
也许您会对这个答案感兴趣。 - Schorsch
2个回答

25

经过一些研究,我想出了两种不同的解决方案。

必需:数据文件分割

这两种解决方案都需要将数据文件按列分类拆分成多个文件。因此,我创建了一个简短的ruby脚本,可以在此gist中找到:

https://gist.github.com/fiedl/6294424

使用此脚本的方法是:要将数据文件data.csv拆分为data.Category1.csvdata.Category2.csv,请运行以下命令:

# bash
ruby categorize_csv.rb --column 2 data.csv

# data.csv
# year   category   num_of_events_for_A   num_of_events_for_B
"2011";"Category1";"213";"30"
"2011";"Category2";"240";"28"
"2012";"Category1";"222";"13"
"2012";"Category2";"238";"42"
...

# data.Category1.csv
# year   category   num_of_events_for_A   num_of_events_for_B
"2011";"Category1";"213";"30"
"2012";"Category1";"222";"13"
...

# data.Category2.csv
# year   category   num_of_events_for_A   num_of_events_for_B
"2011";"Category2";"240";"28"
"2012";"Category2";"238";"42"
...

解决方案1:堆叠箱形图

策略:每个类别一个数据文件。每个堆栈一个列。通过使用 gnuplot 的 "with boxes" 参数手动绘制直方图的条形。

优点:完全灵活,可以自由调整条形大小、帽子、颜色等。

缺点:必须手动放置条形。

# solution1.gnuplot
reset
set terminal postscript eps enhanced 14

set datafile separator ";"

set output 'stacked_boxes.eps'

set auto x
set yrange [0:300]
set xtics 1

set style fill solid border -1

num_of_categories=2
set boxwidth 0.3/num_of_categories
dx=0.5/num_of_categories
offset=-0.1

plot 'data.Category1.csv' using ($1+offset):($3+$4) title "Category 1 A" linecolor rgb "#cc0000" with boxes, \
     ''                   using ($1+offset):3 title "Category 2 B" linecolor rgb "#ff0000" with boxes, \
     'data.Category2.csv' using ($1+offset+dx):($3+$4) title "Category 2 A" linecolor rgb "#00cc00" with boxes, \
     ''                   using ($1+offset+dx):3 title "Category 2 B" linecolor rgb "#00ff00" with boxes

结果看起来像这样:

stacked_boxes.eps

方案二:本机 Gnuplot 直方图

策略:每年一个数据文件。每个堆栈一列。使用 gnuplot 的常规直方图机制生成直方图。

优点:更易于使用,因为不需要手动定位。

缺点:由于所有类别都在一个文件中,每个类别的颜色都相同。

# solution2.gnuplot
reset
set terminal postscript eps enhanced 14

set datafile separator ";"

set output 'histo.eps'
set yrange [0:300]

set style data histogram
set style histogram rowstack gap 1
set style fill solid border -1
set boxwidth 0.5 relative

plot newhistogram "2011", \
       'data.2011.csv' using 3:xticlabels(2) title "A" linecolor rgb "red", \
       ''              using 4:xticlabels(2) title "B" linecolor rgb "green", \
     newhistogram "2012", \
       'data.2012.csv' using 3:xticlabels(2) title "" linecolor rgb "red", \
       ''              using 4:xticlabels(2) title "" linecolor rgb "green", \
     newhistogram "2013", \
       'data.2013.csv' using 3:xticlabels(2) title "" linecolor rgb "red", \
       ''              using 4:xticlabels(2) title "" linecolor rgb "green"
结果看起来像这样:

histo.eps

参考资料


我也认为,将数据文件拆分是创建这些直方图的唯一可行方式。顺便说一句:你也可以接受自己的答案 :) - Christoph
谢谢@Christoph,我想我会等几天,也许有人会添加更好的方法来完成它。 - fiedl
请查看:http://gnuplot.sourceforge.net/demo/histograms.8.gnu。也许解决方案1的颜色可以不同。 - Mingliang Liu

1
非常感谢 @fiedl!基于您的解决方案#1,我可以使用超过两个堆叠子类别来创建自己的堆叠/聚合直方图。

这是我的代码:

set terminal pngcairo  transparent enhanced font "arial,10" fontscale 1.0 size 600, 400 
set output 'runtimes.png'

set xtics("1" 1, "2" 2, "4" 3, "8" 4)
set yrange [0:100]

set style fill solid border -1
set key invert
set grid

num_of_ksptypes=2
set boxwidth 0.5/num_of_ksptypes
dx=0.5/num_of_ksptypes
offset=-0.12

set xlabel "threads"
set ylabel "seconds"

plot 'data1.dat' using ($1+offset):($2+$3+$4+$5) title "SDO" linecolor rgb "#006400" with boxes, \
         ''                   using ($1+offset):($3+$4+$5) title "BGM" linecolor rgb "#FFFF00" with boxes, \
         ''                   using ($1+offset):($4+$5) title "TSQR" linecolor rgb "#FFA500 " with boxes, \
         ''                   using ($1+offset):5 title "SpMV" linecolor rgb "#FF0000" with boxes, \
         'data2.dat' using ($1+offset+dx):($2+$3) title "MGS" linecolor rgb "#8B008B" with boxes, \
         ''                   using ($1+offset+dx):3 title "SpMV" linecolor rgb "#0000FF" with boxes

data1.dat:

nr  SDO  BGM  TSQR  SpMV
1   10   15   20    25
2   10   10   10    10
3   10   10   10    10
4   10   10   10    10

data2.dat:

nr  MGS  SpMV
1   23   13
2   23   13
3   23   13
4   23   13

生成的图表:

enter image description here


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