gnuplot 为什么警告:字符串中的时间格式错误

gnuplot why warning: Bad time format in string

你好,新年快乐 gnuplot 的用户,我有这样的数据存储:

France,FRA,Europe,67012883,cases,0,2020-01,,0,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,0,2020-02,0,0,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,0,2020-03,0,0,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,3,2020-04,0.00447675113455423,3,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,3,2020-05,0.00895350226910846,6,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,5,2020-06,0.011938003025478,11,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,1,2020-07,0.00895350226910846,12,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,0,2020-08,0.00149225037818474,12,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,118,2020-09,0.1760855446258,130,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,996,2020-10,1.66236692129781,1126,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,4297,2020-11,7.89848125173185,5423,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,10595,2020-12,22.2225926319272,16018,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,24156,2020-13,51.857192892298,40174,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,30304,2020-14,81.2679555959412,70478,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,24925,2020-15,82.4154961367652,95403,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,17203,2020-16,62.8655239321669,112606,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,11969,2020-17,43.5319280324053,124575,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,6712,2020-18,27.8767293148692,131287,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,7776,2020-19,21.6197234791406,139063,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,3348,2020-20,16.5997932069271,142411,"Epidemic intelligence, national weekly data"
France,FRA,Europe,67012883,cases,2510,2020-21,8.74160271540623,144921,"Epidemic intelligence, national weekly data"

我的脚本:

reset
set terminal pngcairo size 800,600
set output 'test.png'
set datafile separator ","
set xdata time
set timefmt "%Y-%W"
#set format x "%s" timedate
set xtics format "%s" 
set grid

plot '<grep cases |grep France data1.csv' u 7:6 t 'Nbre cases France' w l lw 1

错误:

France,FRA,Europe,67012883,deaths,2638,2020-51,80.4919853992851,60549,"Epidem...
<grep cases |grep France data1.csv:102:"covid.gnu", line 11: warning: Bad time format in string

为什么我会收到此错误消息?我卡住了,我的数据没有绘制出来。

我看到两个问题。

  1. 输入时忽略时间格式“%W”。请参阅内部文档 help time_specifiers。如果您想将其解释为“第 N 周第一天的第一秒”之类的内容,您必须自己进行计算,因为 gnuplot 不会为您执行此操作。

  2. shell 命令 grep cases |grep France data1.csv 格式错误。如果您将其替换为 grep France data1.csv,程序将无误地执行,但由于问题 (1),它不会生成您可能想要的情节,因为第 # 周丢失了。

这里是更正版本的起点:

set datafile separator ","
set xdata time
timefmt = "%Y-%W"
set xtics time format timefmt
set grid

SECPERWEEK = 3600.*24.*7.
Y_W(col) = timecolumn(col,timefmt) + SECPERWEEK * (strcol(col)[6:7] - 1)

plot 'data1.csv' u (Y_W(7)):6 t 'Nbre cases France' w l lw 1

尽管 OP 已经对答案感到满意,但让我对周数发表评论。它不会改变绘图的形状,但在某些情况下,周数到绝对日期的映射可能是错误的。

不幸的是,从 help time_specifiers 的 gnuplot 文档中,不清楚说明符是否对输出有效或输入有效或两者都有效。 显然,%W 仅用于输出。

注意: 周数有不同的定义(参见:https://en.wikipedia.org/wiki/ISO_week_date

  1. 通常在美国:第 1 周是包含一年中的 1 月 1 日的那一周。周从星期日开始。

  2. 根据 ISO 8601,通常在世界“其他”地区:第 1 周是一年中的第一个星期四,周从星期一开始。或者换句话说:第一周是新年中天数较多的一周。

检查日历周数或周数,我注意到 gnuplot 的实现一定有问题。简单示例:

代码:

### wrong calendar weeks or week numbers in gnuplot
reset session

StartDate = "24.12.2020"
myTimeFmt = "%d.%m.%Y"
SecondsPerDay = 3600*24
do for [i=0:20] {
    myDate = strftime("%a, ".myTimeFmt, strptime(myTimeFmt,StartDate) + i*SecondsPerDay)
    myWeek = strftime("%W", strptime(myTimeFmt,StartDate) + i*SecondsPerDay)
    print sprintf("%s W:%s", myDate, myWeek)
}
### end of code

结果:

Thu, 24.12.2020 W52
Fri, 25.12.2020 W52
Sat, 26.12.2020 W52
Sun, 27.12.2020 W52
Mon, 28.12.2020 W53
Tue, 29.12.2020 W53
Wed, 30.12.2020 W53
Thu, 31.12.2020 W53
Fri, 01.01.2021 W01
Sat, 02.01.2021 W01
Sun, 03.01.2021 W00
Mon, 04.01.2021 W01
Tue, 05.01.2021 W01
Wed, 06.01.2021 W01
Thu, 07.01.2021 W01
Fri, 08.01.2021 W01
Sat, 09.01.2021 W01
Sun, 10.01.2021 W01
Mon, 11.01.2021 W02
Tue, 12.01.2021 W02
Wed, 13.01.2021 W02

所以,有 W52W53W01W00(???) 和 W01...这里错了。我会在有时间找到解决方法后立即更新此答案。

根据 gnuplot 5.2 文档:

%U 一年中的第几周(星期从星期日开始)和

一年中的第 W 周(周从星期一开始)

但是我还没有找到关于输入或输出的信息。

这里的代码与你的 @theozh 相同,但添加了 %U :

### wrong calendar weeks or week numbers in gnuplot
reset session

StartDate = "24.12.2020"
myTimeFmt = "%d.%m.%Y"
SecondsPerDay = 3600*24
do for [i=0:20] {
    myDate = strftime("%a, ".myTimeFmt, strptime(myTimeFmt,StartDate) + i*SecondsPerDay)
    myWeek = strftime("%W", strptime(myTimeFmt,StartDate) + i*SecondsPerDay)
    myWeekUS = strftime("%U", strptime(myTimeFmt,StartDate) + i*SecondsPerDay)
    print sprintf("%s W:%s U:%s", myDate, myWeek, myWeekUS)
}
### end of code

结果:

Thu, 24.12.2020 W:52 U:52
Fri, 25.12.2020 W:52 U:52
Sat, 26.12.2020 W:52 U:52
Sun, 27.12.2020 W:52 U:53
Mon, 28.12.2020 W:53 U:53
Tue, 29.12.2020 W:53 U:53
Wed, 30.12.2020 W:53 U:53
Thu, 31.12.2020 W:53 U:53
Fri, 01.01.2021 W:01 U:01
Sat, 02.01.2021 W:01 U:01
Sun, 03.01.2021 W:00 U:01
Mon, 04.01.2021 W:01 U:01
Tue, 05.01.2021 W:01 U:01
Wed, 06.01.2021 W:01 U:01
Thu, 07.01.2021 W:01 U:01
Fri, 08.01.2021 W:01 U:01
Sat, 09.01.2021 W:01 U:01
Sun, 10.01.2021 W:01 U:02
Mon, 11.01.2021 W:02 U:02
Tue, 12.01.2021 W:02 U:02
Wed, 13.01.2021 W:02 U:02

在这种情况下 (%U),我们避免了 U00,但我们仍然得到 U53(5 天)和 U01(9 天)。