我可以想到三种方法来实现这个。如果你不需要在同一坐标轴上显示那些日期,第二种方法可能是最稳定的。第一种和第三种方法都有各自的优缺点。在这两种方法之间,第三种可能是更好的方法,但它需要更多的工作。
为了确保数据跨越超过1天,在这些示例中,我使用了您的相同数据,但添加了一个额外的行。
31.07.2012 19:30:04
所有三种方法都适用于5.0版本。
在4.6版本中,方法1无法正确对齐,但可以通过添加一个额外的命令来实现。
方法2应该适用于任何较新的版本。
由于迭代中存在溢出错误(请参见此处了解一些解释),因此方法3将无法在4.6版本中放置所有日期标签,但可以通过更改迭代以放置标签来使其工作。
方法1-多图
我们可以使用multiplot将相同的图形叠加在一起,并每次使用不同的x轴来完成此操作。
set datafile separator ";"
set xdata time
set timefmt "%d.%m.%Y %H:%M:%S"
# Increase bottom margin to allow room for dates
set bmargin at screen 0.1
set multiplot layout 1,1
# tics starting at 0 every 6 hours showing hour
set xtics 0,60*60*6 format "%H"
plot "data.csv" using 1:2 with lines t "Temperature"
# Tics starting at 0 every 24 hours showing day.month
# moved down by 1 character to be under hours
set xtics 0,60*60*24 format "%d.%m" offset 0,-1
set origin 0,0 # This is not needed in version 5.0
replot
unset multiplot
除了坐标轴标签的差异外,图表必须完全相同,以避免它们不对齐,并且会使y轴标签略微加粗,因为它们重叠在一起。
在5.0版本中,不需要使用“set origin”命令,但在4.6版本中需要。
方法二-次要轴
如果使用次要轴是可以接受的,您也可以采用这种方法。例如,如果日期显示在x2轴上,小时显示在x1轴上,我们可以这样做。
set datafile separator ";"
set xdata time
set x2data time
set timefmt "%d.%m.%Y %H:%M:%S"
set xtics 0,60*60*6 format "%H"
set x2tics 0,60*60*24 format "%d.%m"
plot "data.csv" using 1:2 with lines t "Temperature"
这消除了多绘图方法的一些问题,但导致两个数据标签位于不同的轴上。
第三种方法-手动设置标签
最后,我们可以手动设置标签。幸运的是,在最新版本的gnuplot中,我们可以使用循环,因此不必为其发出单独的命令,但我们必须自己计算标签。
我们可以使用stats命令计算标签。如果我们给它时间数据,stat命令将抱怨,因此我们必须在打开时间模式之前使用它,并且我们必须做一些工作来计算日边界。为了确保我们正在处理每天的开始而不是在中间某个时候,我们将日期解析为内部表示形式(自Unix纪元以来的秒数),并向下舍入到最近的86400的倍数(一天的秒数)。
总体上,我们可以做如下操作:
# in-large margin for date labels
set bmargin at screen 0.1
set datafile separator ";"
# Get first and last day in data file as STATS_min and STATS_max
stats "data.csv" u (floor(strptime("%d.%m.%Y %H:%M:%S",stringcolumn(1))/86400)*86400) nooutput
set xdata time
set timefmt "%d.%m.%Y %H:%M:%S"
set for [i=STATS_min:(STATS_max+86400):86400] label strftime("%d.%m",i) at i,graph 0 center offset 0,char -2
# set xtics every 6 hours
set xtics 0,60*60*6 format "%H"
plot "data.csv" using 1:2 with lines t "Temperature"
我们可以通过为标签编号来改进它,如果以后需要删除它们(
(i-STATS_min)/86400+1
将使它们编号为1、2、3等)。请注意,与第一种方法一样,我们需要增加底部的边距大小。我在标签上添加了一天的额外时间,以覆盖gnuplot在x轴上可能进行的四舍五入。
在版本4.6中,存在处理迭代和整数溢出的错误。要在4.6中使用此解决方案,请更改
set for [i=STATS_min:(STATS_max+86400):86400] label strftime("%d.%m",i) at i,graph 0 center offset 0,char -2
到
days = (STATS_max-STATS_min)/86400+1
set for [i=0:days] label strftime("%d.%m",i*86400+STATS_min) at (i*86400+STATS_min),graph 0 center offset 0,char -2