如何在 gnuplot 5.4 中绘制月份数字?

How to plot month numbers in gnuplot 5.4?

我正在尝试获取 gnuplot 5.4 中日期的月份。

考虑以下数据:

2019/01/01
2019/02/01
2019/03/01
2019/04/01
2019/05/01
2019/06/01
2019/07/01
2019/08/01
2019/09/01
2019/10/01
2019/11/01
2019/12/01
2020/01/01
2020/02/01
2020/03/01
2020/04/01
2020/05/01
2020/06/01
2020/07/01
2020/08/01
2020/09/01
2020/10/01
2020/11/01
2020/12/01

对于每个数据点,我想在 x 轴上显示完整日期,在 y 轴上显示月份数 (0-11)。

gnuplot 文档建议对此类任务使用 tm_mon function,它应该 return 给定日期的月份数。

据我了解,以下 gnuplot 脚本应该可以满足我的要求:

#!/bin/gnuplot
set timefmt '%Y/%m/%d'
set xdata time
set format x '%m/%y'
set datafile separator ','

plot "data.csv" using 1:(tm_mon()) title 'data'

但事实并非如此。此 gnuplot 脚本在 x 轴上正确显示日期,但在 y 轴上有一个常量 0

我做错了什么?为什么 tm_mon() 经常 return 为 0?

我不确定我是否完全理解你的意图。 我知道您希望第 1 列作为 xtic 标签。 但是,仅将第 1 列作为 xtic 标签或将第 1 列解释为 date/time 并相应地缩放 x 轴是有区别的,gnuplot 会自动处理 xtic 标签。 对于第一种情况,图表的宽度可能不足以显示所有标签而不重叠,因此,我重新格式化了日期。检查 help strptimehelp strftime。顺便说一下,help tm_mon 说它需要以秒为单位输入,而不是像 </code> 中那样以您的日期格式输入,供使用 <code>strptime().

我了解到您希望一年中的几个月的范围从 1 到 12。 但是您要绘制的数据在哪里? 也许以下示例是更好地找出您真正想要的东西的起点。

代码:

### plotting dates...
reset session

$Data <<EOD
2019/01/01
2019/02/01
2019/03/01
2019/04/01
2019/05/01
2019/06/01
2019/07/01
2019/08/01
2019/09/01
2019/10/01
2019/11/01
2019/12/01
2020/01/01
2020/02/01
2020/03/01
2020/04/01
2020/05/01
2020/06/01
2020/07/01
2020/08/01
2020/09/01
2020/10/01
2020/11/01
2020/12/01
EOD

myTimeInputFmt = "%Y/%m/%d"
myTimeOutputXFmt = "%Y\n%m\n%d"
set xlabel "Date"
set format x myTimeOutputXFmt   # to get enough space for the 3 lines of the label

set ylabel "Month"
set yrange [0.5:12.5]
set ytics 1

plot $Data u 0:(tm_mon(strptime(myTimeInputFmt,strcol(1)))+1): \
             xtic(strftime(myTimeOutputXFmt,strptime(myTimeInputFmt,strcol(1)))) \
             with points pt 7 lc "red" title 'data'
### end of code

结果:

另一种正确读取数据的方法

gnuplot中也有函数'timecolumn(N, "timeformat")',虽然只能在using中使用。这是将第 N 列输入数据读取为日期时间的函数。如果您使用 set timefmt 给出的格式,则此函数的第二个参数是可选的。有了它,您的脚本将按以下脚本运行。

#!/bin/gnuplot
set timefmt '%Y/%m/%d'
set xdata time
set format x '%m/%y'
set datafile separator ','

plot "data.csv" using 1:(tm_mon(timecolumn(1))) title 'data'

为什么 tm_mon($1) 不断返回 0?

在您的脚本中,当从 'data.csv' 读取第一行时,tm_mon() 被解释为 tm_mon("2019/01/01")tm_mon 基本上接受表示 UNIX 时间的实际值作为参数。但是,如果给定字符串值,tm_mon 会尝试将其转换为实际值并解释为 UNIX 时间。因此,tm_mon 不会不断返回 0。您可以通过尝试以下命令来了解此行为。

gnuplot> print tm_mon(1607698800)    ### 2020-12-12 in UNIX time
11.0
gnuplot> print tm_mon("1607698800")
11.0
gnuplot> print tm_mon("1607698800/05/06")
11.0