使用 gnuplot 的时间序列数据堆叠直方图?
Stacked histogram with time series data with gnuplot?
我有很多这样的数据
callr | method | call_count | day
------+-------------------------+------------
foo | find_paths | 10 | 2016-10-10
bar | find_paths | 100 | 2016-10-10
foo | find_all | 123 | 2016-10-10
foo | list_paths | 2243 | 2016-10-10
foo | find_paths | 234 | 2016-10-11
foo | collect | 200 | 2016-10-11
bar | collect | 1 | 2016-10-11
baz | collect | 3 | 2016-10-11
... ... ... ...
我想为每种方法创建一个堆叠直方图,显示底部的连续天数和每天的堆叠条,以及呼叫者和呼叫次数。
如果我转换数据,例如
select method, sum(call_count), day from foo where method='collect' group by method, day order by method, day;
我能够得到一个条形图,其中包含一种颜色的一种方法的所有调用,使用这样的 plg 文件,例如:
set terminal png
set title "Method: " . first_arg
set output "" . first_arg . ".png"
set datafile separator '|'
set style data boxes
set style fill solid
set boxwidth 0.5
set xdata time
set timefmt "%Y-%m-%d"
set format x "%a %m-%d"
xstart="2016-10-01"
xend="2017-01-01"
set xrange [xstart:xend]
set xlabel "Date" tc ls 8 offset -35, -3
set ylabel "Calls" tc ls 8
plot '<cat' using 3:4
这样调用:
cat file | gnuplot -p -e "plot '<cat';first_arg='collect'" calls.plg
但是,我真正想要的是一种在同一种图表中按呼叫者显示细分的方法。我还无法使用 gnuplot 获得堆叠直方图。
我尝试过的一切都抱怨 using 声明,例如'Need full using spec for x time data' 之类的。
想要这样的东西,但底部的日子是连续的。例如。如果那天没有打电话 - 那么没有直方图条
感谢您的任何想法
使用 smooth freq
和 bin()
将纪元时间四舍五入到天的函数合并每天的数据。使用内联 for
和求和表达式将 y 轴类别的总和绘制为按高度降序排列的框,以便总和之间的差异等于类别的值。因此,最高的盒子高度为 foo+bar+baz (caller=3
),次高的盒子为 foo+bar (caller=2
),最矮的盒子只有 foo (caller=1
)。
calls
:
caller method call_count day
foo find_paths 10 2016-10-10
bar find_paths 100 2016-10-10
foo find_all 123 2016-10-10
foo list_paths 2243 2016-10-10
foo find_paths 234 2016-10-11
foo collect 200 2016-10-11
bar collect 1 2016-10-11
baz collect 3 2016-10-11
gnuplot 脚本:
binwidth = 86400
bin(t) = (t - (int(t) % binwidth))
date_fmt = "%Y-%m-%d"
time = '(bin(timecolumn(4, date_fmt)))'
# Set absolute boxwidth so all boxes get plotted fully. Otherwise boxes at the
# edges of the range can get partially cut off, which I think looks weird.
set boxwidth 3*binwidth/4 absolute
set key rmargin
set xdata time
set xtics binwidth format date_fmt time rotate by -45 out nomirror
set style fill solid border lc rgb "black"
callers = system("awk 'NR != 1 {print }' calls \
| sort | uniq -c | sort -nr | awk '{print }'")
# Or, if Unix tools aren't available:
# callers = "foo bar baz"
plot for [caller=words(callers):1:-1] 'calls' \
u @time:(sum [i=1:caller] \
strcol("caller") eq word(callers, i) ? column("call_count") : 0) \
smooth freq w boxes t word(callers, caller)
我在这里写了一篇关于 gnuplot 时间序列直方图的较长讨论:Time-series histograms: gnuplot vs matplotlib
参考 https://psy.swansea.ac.uk/staff/Carter/gnuplot/gnuplot_time_histograms.htm 了解实用的解决方案,尤其是其最后一节“箱线图”。
该解决方案包括使用添加功能($2+$3...),同时明确使用“带框”。
我有很多这样的数据
callr | method | call_count | day
------+-------------------------+------------
foo | find_paths | 10 | 2016-10-10
bar | find_paths | 100 | 2016-10-10
foo | find_all | 123 | 2016-10-10
foo | list_paths | 2243 | 2016-10-10
foo | find_paths | 234 | 2016-10-11
foo | collect | 200 | 2016-10-11
bar | collect | 1 | 2016-10-11
baz | collect | 3 | 2016-10-11
... ... ... ...
我想为每种方法创建一个堆叠直方图,显示底部的连续天数和每天的堆叠条,以及呼叫者和呼叫次数。
如果我转换数据,例如
select method, sum(call_count), day from foo where method='collect' group by method, day order by method, day;
我能够得到一个条形图,其中包含一种颜色的一种方法的所有调用,使用这样的 plg 文件,例如:
set terminal png
set title "Method: " . first_arg
set output "" . first_arg . ".png"
set datafile separator '|'
set style data boxes
set style fill solid
set boxwidth 0.5
set xdata time
set timefmt "%Y-%m-%d"
set format x "%a %m-%d"
xstart="2016-10-01"
xend="2017-01-01"
set xrange [xstart:xend]
set xlabel "Date" tc ls 8 offset -35, -3
set ylabel "Calls" tc ls 8
plot '<cat' using 3:4
这样调用:
cat file | gnuplot -p -e "plot '<cat';first_arg='collect'" calls.plg
但是,我真正想要的是一种在同一种图表中按呼叫者显示细分的方法。我还无法使用 gnuplot 获得堆叠直方图。 我尝试过的一切都抱怨 using 声明,例如'Need full using spec for x time data' 之类的。
想要这样的东西,但底部的日子是连续的。例如。如果那天没有打电话 - 那么没有直方图条
感谢您的任何想法
使用 smooth freq
和 bin()
将纪元时间四舍五入到天的函数合并每天的数据。使用内联 for
和求和表达式将 y 轴类别的总和绘制为按高度降序排列的框,以便总和之间的差异等于类别的值。因此,最高的盒子高度为 foo+bar+baz (caller=3
),次高的盒子为 foo+bar (caller=2
),最矮的盒子只有 foo (caller=1
)。
calls
:
caller method call_count day
foo find_paths 10 2016-10-10
bar find_paths 100 2016-10-10
foo find_all 123 2016-10-10
foo list_paths 2243 2016-10-10
foo find_paths 234 2016-10-11
foo collect 200 2016-10-11
bar collect 1 2016-10-11
baz collect 3 2016-10-11
gnuplot 脚本:
binwidth = 86400
bin(t) = (t - (int(t) % binwidth))
date_fmt = "%Y-%m-%d"
time = '(bin(timecolumn(4, date_fmt)))'
# Set absolute boxwidth so all boxes get plotted fully. Otherwise boxes at the
# edges of the range can get partially cut off, which I think looks weird.
set boxwidth 3*binwidth/4 absolute
set key rmargin
set xdata time
set xtics binwidth format date_fmt time rotate by -45 out nomirror
set style fill solid border lc rgb "black"
callers = system("awk 'NR != 1 {print }' calls \
| sort | uniq -c | sort -nr | awk '{print }'")
# Or, if Unix tools aren't available:
# callers = "foo bar baz"
plot for [caller=words(callers):1:-1] 'calls' \
u @time:(sum [i=1:caller] \
strcol("caller") eq word(callers, i) ? column("call_count") : 0) \
smooth freq w boxes t word(callers, caller)
我在这里写了一篇关于 gnuplot 时间序列直方图的较长讨论:Time-series histograms: gnuplot vs matplotlib
参考 https://psy.swansea.ac.uk/staff/Carter/gnuplot/gnuplot_time_histograms.htm 了解实用的解决方案,尤其是其最后一节“箱线图”。 该解决方案包括使用添加功能($2+$3...),同时明确使用“带框”。