首页 > 解决方案 > gnuplot:如何获得正确的周数?

问题描述

源自这个问题gnuplot why warning: Bad time format in string,发现 gnuplot 中的周数使用时间说明符%W并且%U在某些情况下是错误的。

显然,周数有不同的定义。此外,一周的开始时间有不同的定义,例如周日或周一。根据 ISO 8601,一种常用的周数定义(但在美国和其他一些国家/地区不适用)。

代码:(说明错误的周数)

### wrong week numbering in gnuplot with %W and %U
reset session

StartDate = "24.12.2020"
myTimeFmt = "%d.%m.%Y"
SecondsPerDay = 3600*24

print "      date   %a  %w  %d   %j  %W  %U"
print "===================================="
do for [i=0:20] {
    t = strptime(myTimeFmt,StartDate) + i*SecondsPerDay
    myDate = strftime(myTimeFmt."  %a  %w  %d  %j  %W  %U", t)
    print sprintf("%s", myDate)
}
### end of code

gnuplot 时间说明符:

%a abbreviated name of day of the week
%w day of the week, 0–6 (Sunday = 0)
%d day of the month, 01–31
%j day of the year, 1–366 
%W week of the year (week starts on Monday)
%U week of the year (week starts on Sunday)

结果:

      date   %a  %w  %d   %j  %W  %U
====================================
24.12.2020  Thu  04  24  359  52  52
25.12.2020  Fri  05  25  360  52  52
26.12.2020  Sat  06  26  361  52  52
27.12.2020  Sun  00  27  362  52  53
28.12.2020  Mon  01  28  363  53  53
29.12.2020  Tue  02  29  364  53  53
30.12.2020  Wed  03  30  365  53  53
31.12.2020  Thu  04  31  366  53  53
01.01.2021  Fri  05  01  001  01  01   ???
02.01.2021  Sat  06  02  002  01  01   ???
03.01.2021  Sun  00  03  003  00  01   ???
04.01.2021  Mon  01  04  004  01  01
05.01.2021  Tue  02  05  005  01  01
06.01.2021  Wed  03  06  006  01  01
07.01.2021  Thu  04  07  007  01  01
08.01.2021  Fri  05  08  008  01  01
09.01.2021  Sat  06  09  009  01  01
10.01.2021  Sun  00  10  010  01  02
11.01.2021  Mon  01  11  011  02  02
12.01.2021  Tue  02  12  012  02  02
13.01.2021  Wed  03  13  013  02  02

问题:是否有解决方法来解决此问题?

标签: gnuplotweek-number

解决方案


鉴于持续的大流行以及随之而来的对绘制所有来源的流行病学数据的兴趣,清理和扩展 gnuplot 对周日期格式的支持似乎是权宜之计。gnuplot 文档的“新功能”部分现在列出:

• Time specifier format %W has been brought into accord with the ISO 8601 week date standard. 
• Time specifier format %U has been brought into accord with the CDC/MMWR week date standard. 
• New function tm week(time, std) returns ISO or CDC standard week of year. 
• New function weekdate iso(year, week, day) converts ISO standard week date to calendar time. 
• New function weekdate cdc(year, week, day) converts CDC standard week date to calendar time.

这是一个示例(来自在线演示集),它将以 ISO 8601 周日期格式给出的数据转换为标准日历日期,以便沿 gnuplot 时间轴绘制。

#                   Epidemiological data
#
# Plot from data file that encodes date as an ISO 8601 "week date".
# Example:  week date 2004-W01-1 is calendar date 29 December 2003
# The data is from the European Centre for Disease Prevention and Control
# https://www.ecdc.europa.eu/

# The ECDC data file uses fields containing week date as "YYYY-WW".
# First we define a function that extracts the integer year and week
# from this string and converts it to standard time representation.

calendar(date) = weekdate_iso( int(date[1:4]), int(date[6:7]) )

set datafile separator comma
set style data lines
set key Left left reverse box samplen 2 width 2
set grid x lt 1 lw .75 lc "gray"
set tics nomirror
set border 3
set xtics time format "%b\n%Y"
set ytics format " %4.0f"

data1 = '< grep "Denmark.*cases" ECDC-weekly-national-COVID.csv'
data2 = '< grep "Sweden.*cases" ECDC-weekly-national-COVID.csv'
data3 = '< grep "Norway.*cases" ECDC-weekly-national-COVID.csv'
data4 = '< grep "Finland.*cases" ECDC-weekly-national-COVID.csv'
data5 = '< grep "Iceland.*cases" ECDC-weekly-national-COVID.csv'

set title "weekly COVID-19 cases per 100,000 people" font "/Bold,15"

plot data1 using (calendar(strcol(7))) : (1.e5*$6/$4) lw 2 title "Denmark", \
     data2 using (calendar(strcol(7))) : (1.e5*$6/$4) lw 2 title "Sweden", \
     data3 using (calendar(strcol(7))) : (1.e5*$6/$4) lw 2 title "Norway", \
     data4 using (calendar(strcol(7))) : (1.e5*$6/$4) lw 2 title "Finland", \
     data5 using (calendar(strcol(7))) : (1.e5*$6/$4) lw 2 lt 6 title "Iceland"

在此处输入图像描述


推荐阅读