gnuplot 自动堆栈条形图
gnuplot automatic stack bar graph
这是我的数据集:
type size name
label_0 1 nameOfData_0
label_0 2 nameOfData_1
label_0 3 nameOfData_2
label_1 2 nameOfData_3
label_2 1 nameOfData_4
label_0 2 nameOfData_5
label_1 3 nameOfData_6
label_3 2 nameOfData_7
label_3 1 nameOfData_8
我希望情节看起来像:
我希望每个标签都是一个堆栈,并且每个 nameOfData_X 都可以根据其大小放入正确的堆栈中。如果可能,还为堆栈的每个元素添加图例。
我知道我可以重新格式化数据以便通过 gnuplot 轻松处理它,但我不想这样做。
关于如何通过 gnuplot 显示此图有什么想法吗?
感谢您的帮助!
也许有一种方法可以使用 gnuplot 内置的堆叠直方图样式来实现这一点,检查 help histograms
。
以下解决方案不太明显,但似乎给出了所需的结果并使用绘图样式 with boxxyerror
(检查 help boxxyerror
)。
- 您需要第 1 列的唯一元素列表。此处将按第一次出现的顺序排列。
- 在循环绘图期间,您根据“过滤器”函数添加您的贡献
myAdd()
。
- 你在加法为零时改变颜色(
dy=0
)。
- 您以类似的方式添加带有偏移量的标签
这段代码或许可以简化,但可以作为起点。
代码:
### "manual" stacked histogram
reset session
$Data <<EOD
type size name
label_0 1 nameOfData_0
label_0 2 nameOfData_1
label_0 3 nameOfData_2
label_1 2 nameOfData_3
label_2 1 nameOfData_4
label_0 2 nameOfData_5
label_1 3 nameOfData_6
label_3 2 nameOfData_7
label_3 1 nameOfData_8
EOD
# get a unique list from datablock column 1
set table $Dummy
Headers = 1
addToList(list,col) = list.( strstrt(list,'"'.strcol(col).'"') > 0 ? '' : \
' "'.strcol(col).'"')
plot Uniques='' $Data u (Uniques=addToList(Uniques,1),'') skip Headers w table
unset table
N = words(Uniques)
Unique(i) = word(Uniques,i)
set xrange [1:N]
set xtics out noenhanced
set grid x,y
set offsets 0.5,0.5,0.5,0
unset key
set style fill transparent solid 0.7 border
myBoxWidth = 0.8
myAdd(colD,colF,i) = strcol(colF) eq Unique(i) ? column(colD) : 0
myLabel(col1,col2) = dy==0 ? '' : sprintf("%s\n%g",strcol(col1),column(col2))
plot for [i=1:N] y=y0=(c=1,0) $Data u (i):(dy=myAdd(2,1,i), y=y+dy,(y0+y)/2.): \
(myBoxWidth/2.):(y0=y,dy/2.):(dy==0?c:c=c+1) skip Headers w boxxy lc variable, \
for [i=1:N] y=y0=0 $Data u (i):(dy=myAdd(2,1,i), y=y+dy,(y0+y)/2.): \
(y0=y,myLabel(3,2)):xtic(Unique(i)) skip Headers w labels offset 0,0.5 noenhanced
### end of code
结果:
这是我的数据集:
type size name
label_0 1 nameOfData_0
label_0 2 nameOfData_1
label_0 3 nameOfData_2
label_1 2 nameOfData_3
label_2 1 nameOfData_4
label_0 2 nameOfData_5
label_1 3 nameOfData_6
label_3 2 nameOfData_7
label_3 1 nameOfData_8
我希望情节看起来像:
我希望每个标签都是一个堆栈,并且每个 nameOfData_X 都可以根据其大小放入正确的堆栈中。如果可能,还为堆栈的每个元素添加图例。
我知道我可以重新格式化数据以便通过 gnuplot 轻松处理它,但我不想这样做。
关于如何通过 gnuplot 显示此图有什么想法吗?
感谢您的帮助!
也许有一种方法可以使用 gnuplot 内置的堆叠直方图样式来实现这一点,检查 help histograms
。
以下解决方案不太明显,但似乎给出了所需的结果并使用绘图样式 with boxxyerror
(检查 help boxxyerror
)。
- 您需要第 1 列的唯一元素列表。此处将按第一次出现的顺序排列。
- 在循环绘图期间,您根据“过滤器”函数添加您的贡献
myAdd()
。 - 你在加法为零时改变颜色(
dy=0
)。 - 您以类似的方式添加带有偏移量的标签
这段代码或许可以简化,但可以作为起点。
代码:
### "manual" stacked histogram
reset session
$Data <<EOD
type size name
label_0 1 nameOfData_0
label_0 2 nameOfData_1
label_0 3 nameOfData_2
label_1 2 nameOfData_3
label_2 1 nameOfData_4
label_0 2 nameOfData_5
label_1 3 nameOfData_6
label_3 2 nameOfData_7
label_3 1 nameOfData_8
EOD
# get a unique list from datablock column 1
set table $Dummy
Headers = 1
addToList(list,col) = list.( strstrt(list,'"'.strcol(col).'"') > 0 ? '' : \
' "'.strcol(col).'"')
plot Uniques='' $Data u (Uniques=addToList(Uniques,1),'') skip Headers w table
unset table
N = words(Uniques)
Unique(i) = word(Uniques,i)
set xrange [1:N]
set xtics out noenhanced
set grid x,y
set offsets 0.5,0.5,0.5,0
unset key
set style fill transparent solid 0.7 border
myBoxWidth = 0.8
myAdd(colD,colF,i) = strcol(colF) eq Unique(i) ? column(colD) : 0
myLabel(col1,col2) = dy==0 ? '' : sprintf("%s\n%g",strcol(col1),column(col2))
plot for [i=1:N] y=y0=(c=1,0) $Data u (i):(dy=myAdd(2,1,i), y=y+dy,(y0+y)/2.): \
(myBoxWidth/2.):(y0=y,dy/2.):(dy==0?c:c=c+1) skip Headers w boxxy lc variable, \
for [i=1:N] y=y0=0 $Data u (i):(dy=myAdd(2,1,i), y=y+dy,(y0+y)/2.): \
(y0=y,myLabel(3,2)):xtic(Unique(i)) skip Headers w labels offset 0,0.5 noenhanced
### end of code
结果: