如何在 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 strptime
和 help 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
我正在尝试获取 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 strptime
和 help 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