在时间序列图中指示周末并在时间序列 gnuplot 中设置 xrange
Indicating weekends in timeseries plot and setting xrange in timeseries gnuplot
使用出色的答案我已经能够绘制我的时间序列数据。
我现在试图指示周末(或有趣的时间段)我的情节并将可见 xrange 设置为 31/1 到 28/2
今年 2 月的周末是 2/5/22 到 2/6/22 和 2/12/22 到 2/13/22 等等 - 我怎么画一个垂直的柱子和阴影来表示周末或其他有趣的时间序列块?我看着尝试使用时间序列点绘制一个矩形,即 weekend1,但我无法填充该形状。然后我试着画了一个矩形,但不知道如何在时间序列格式中指定角来显示它。
因为我的 x 轴是时间序列
- 我如何在图表中指明所有周末 - 有点像在日历或时间表中?
- 如何将 xrange 定义为 1/31/22 到 2/28/22?
reset session
set datafile separator comma
myTimeFmt = "%m/%d/%y, %H:%M %p"
set format x "%d" time
#
# Gives error all points y value undefined!
#
# set xrange ["1/31/22, 12:01 AM":"2/28/22, 11:59 PM"] #
#
# Trying to draw a series to fill to indicate a weekend range - vertically
#
$weekend1 <<EOD
"2/5/22, 12:01 AM",0
"2/5/22, 12:01 AM",600
"2/6/22, 11:59 PM",600
"2/6/22, 11:59 PM",0
EOD
$account <<EOD
"1/31/22, 5:07 PM",1
"1/31/22, 8:01 PM",100
"2/1/22, 11:10 AM",200
"2/6/22, 12:25 PM",300
"2/9/22, 2:02 PM",400
"2/24/22, 4:22 PM",500
EOD
set object 1 rect from 1,1 to 2,2
plot $account u (timecolumn(1,myTimeFmt)):2 w lp pt 1 ps 1 lc "red" lw 1 ti "Account"
#plot $weekend1 u (timecolumn(1,myTimeFmt)):2 w lp pt 1 ps 1 lc "grey"
这是我从您的问题中了解到的内容:绘制一些时间序列数据并通过为背景着色来突出显示周末。
一种可能的方法是在您的时间范围内创建包含所有日期的数据块,并根据工作日绘制彩色框(选中 help boxxyerror
)(选中 help lc variable
)(选中 help tm_wday
).
- 首先你必须在背景中绘制方框,然后是数据
- 背景颜色应跨越整个垂直图形大小。为此,您需要知道数据的 y-range。您可以从
stats
获得 STATS_min
和 STATS_max
(检查 help stats
)。
- 为了跨越整个图表,您可以扩展框的 y-range(通过在顶部和底部再次添加范围)但不要对框应用自动缩放(选中
help noautoscale
).自动缩放将仅用于数据。
- 也许你有一个固定的已知 y-range,那么你可以简单地通过
set yrange
和合适的框大小来设置它。
希望您能根据自己的需要改编以下示例。
代码:
### highlight weekends
reset session
myTimeFmt = "%d.%m.%Y"
DateStart = "01.01.2022"
DateEnd = "28.02.2022"
SecsPerDay = 24*3600
# create some random test data
set print $Data
y=50
do for [t=strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd):SecsPerDay] {
print sprintf('"%s", %g', strftime(myTimeFmt,t),y=y+rand(0)*10-5)
}
set print
# datablock with every day between start and end date
set print $Days
do for [t=strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd):SecsPerDay] {
print strftime(myTimeFmt,t)
}
set print
set datafile separator comma
set key noautotitle
set style fill solid 0.4 border
set format x "%d %b\n%Y" timedate
set xtics out scale 2, 1
DayColor(t) = tm_wday(t)==0 ? 0xff0000 : tm_wday(t)==6 ? 0xffdd00 : 0xdddddd
stats $Data u 2 nooutput # get min and max from column 2
plot $Days u (t=timecolumn(1,myTimeFmt)):(0):(t):(t+SecsPerDay):\
(2*STATS_min-STATS_max):(2*STATS_max+STATS_min):(DayColor(t)) w boxxy lc rgb var noautoscale, \
$Data u (timecolumn(1,myTimeFmt)):2 w lp pt 7 lc "black"
### end of code
结果:
注意: 首先我以为你想绘制一个突出显示周末的日历,但这不是你的问题。因为我已经有了以下代码(它将绘制两个不同版本的日历),所以我仍然 post 它。也许对你或其他人进一步适配和优化有用。
代码:
### plot a calendar
reset session
myTimeFmt = "%d.%m.%Y"
DateStart = "01.01.2022"
DateEnd = "31.12.2022"
SecsPerDay = 24*3600
set print $Data
do for [t=strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd):SecsPerDay] {
print strftime(myTimeFmt,t)
}
set print
set xrange[0.5:31.5]
set xtics 1 scale 0 offset 0,0.5 font ",8"
set link x2 via x inverse x
set x2tics 1 out scale 0 offset 0,-0.5 font ",8"
set yrange [:] reverse noextend
set ytics 1 scale 0
set key noautotitle
set style fill solid 0.4 border lc "black"
WeekDay(t) = word("S M T W T F S",int(tm_wday(t))+1)
DayColor(t) = tm_wday(t) == 0 ? 0xff0000 : tm_wday(t) == 6 ? 0xffdd00 : 0xdddddd
MonthFirst(t) = int(strptime("%Y%m%d",sprintf("%04d%02d01",tm_year(t),tm_mon(t)+1)))
Month(t) = int(tm_year(t)*12 + tm_mon(t))
MonthName(n) = word("January February March April May June July August September October November December",n)
MonthLabel(t) = sprintf("%s",MonthName(Month(t)%12+1)) # without year
MonthLabel(t) = sprintf("%s %04d",MonthName(Month(t)%12+1),tm_year(t)) # alternatively with year
plot $Data u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(0.5):(0.5):(DayColor(t)): \
xtic(tm_mday(t)):ytic(MonthLabel(t)) w boxxy lc rgb var, \
'' u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(WeekDay(t)) w labels
pause -1
MonthOffset(t) = tm_wday(MonthFirst(t))==0 ? 7 : tm_wday(MonthFirst(t))
set xrange[1.5:*]
plot $Data u (t=timecolumn(1,myTimeFmt), tm_mday(t)+MonthOffset(t)):(Month(t)):(0.5):(0.5):(DayColor(t)): \
xtic(WeekDay(t)):x2tic(WeekDay(t)):ytic(MonthLabel(t)) w boxxy lc rgb var, \
'' u (t=timecolumn(1,myTimeFmt), tm_mday(t)+MonthOffset(t)):(Month(t)):(sprintf("%d",tm_mday(t))) w labels font ",8"
### end of code
结果:
使用出色的答案
我现在试图指示周末(或有趣的时间段)我的情节并将可见 xrange 设置为 31/1 到 28/2
今年 2 月的周末是 2/5/22 到 2/6/22 和 2/12/22 到 2/13/22 等等 - 我怎么画一个垂直的柱子和阴影来表示周末或其他有趣的时间序列块?我看着尝试使用时间序列点绘制一个矩形,即 weekend1,但我无法填充该形状。然后我试着画了一个矩形,但不知道如何在时间序列格式中指定角来显示它。
因为我的 x 轴是时间序列
- 我如何在图表中指明所有周末 - 有点像在日历或时间表中?
- 如何将 xrange 定义为 1/31/22 到 2/28/22?
reset session
set datafile separator comma
myTimeFmt = "%m/%d/%y, %H:%M %p"
set format x "%d" time
#
# Gives error all points y value undefined!
#
# set xrange ["1/31/22, 12:01 AM":"2/28/22, 11:59 PM"] #
#
# Trying to draw a series to fill to indicate a weekend range - vertically
#
$weekend1 <<EOD
"2/5/22, 12:01 AM",0
"2/5/22, 12:01 AM",600
"2/6/22, 11:59 PM",600
"2/6/22, 11:59 PM",0
EOD
$account <<EOD
"1/31/22, 5:07 PM",1
"1/31/22, 8:01 PM",100
"2/1/22, 11:10 AM",200
"2/6/22, 12:25 PM",300
"2/9/22, 2:02 PM",400
"2/24/22, 4:22 PM",500
EOD
set object 1 rect from 1,1 to 2,2
plot $account u (timecolumn(1,myTimeFmt)):2 w lp pt 1 ps 1 lc "red" lw 1 ti "Account"
#plot $weekend1 u (timecolumn(1,myTimeFmt)):2 w lp pt 1 ps 1 lc "grey"
这是我从您的问题中了解到的内容:绘制一些时间序列数据并通过为背景着色来突出显示周末。
一种可能的方法是在您的时间范围内创建包含所有日期的数据块,并根据工作日绘制彩色框(选中 help boxxyerror
)(选中 help lc variable
)(选中 help tm_wday
).
- 首先你必须在背景中绘制方框,然后是数据
- 背景颜色应跨越整个垂直图形大小。为此,您需要知道数据的 y-range。您可以从
stats
获得STATS_min
和STATS_max
(检查help stats
)。 - 为了跨越整个图表,您可以扩展框的 y-range(通过在顶部和底部再次添加范围)但不要对框应用自动缩放(选中
help noautoscale
).自动缩放将仅用于数据。 - 也许你有一个固定的已知 y-range,那么你可以简单地通过
set yrange
和合适的框大小来设置它。
希望您能根据自己的需要改编以下示例。
代码:
### highlight weekends
reset session
myTimeFmt = "%d.%m.%Y"
DateStart = "01.01.2022"
DateEnd = "28.02.2022"
SecsPerDay = 24*3600
# create some random test data
set print $Data
y=50
do for [t=strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd):SecsPerDay] {
print sprintf('"%s", %g', strftime(myTimeFmt,t),y=y+rand(0)*10-5)
}
set print
# datablock with every day between start and end date
set print $Days
do for [t=strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd):SecsPerDay] {
print strftime(myTimeFmt,t)
}
set print
set datafile separator comma
set key noautotitle
set style fill solid 0.4 border
set format x "%d %b\n%Y" timedate
set xtics out scale 2, 1
DayColor(t) = tm_wday(t)==0 ? 0xff0000 : tm_wday(t)==6 ? 0xffdd00 : 0xdddddd
stats $Data u 2 nooutput # get min and max from column 2
plot $Days u (t=timecolumn(1,myTimeFmt)):(0):(t):(t+SecsPerDay):\
(2*STATS_min-STATS_max):(2*STATS_max+STATS_min):(DayColor(t)) w boxxy lc rgb var noautoscale, \
$Data u (timecolumn(1,myTimeFmt)):2 w lp pt 7 lc "black"
### end of code
结果:
注意: 首先我以为你想绘制一个突出显示周末的日历,但这不是你的问题。因为我已经有了以下代码(它将绘制两个不同版本的日历),所以我仍然 post 它。也许对你或其他人进一步适配和优化有用。
代码:
### plot a calendar
reset session
myTimeFmt = "%d.%m.%Y"
DateStart = "01.01.2022"
DateEnd = "31.12.2022"
SecsPerDay = 24*3600
set print $Data
do for [t=strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd):SecsPerDay] {
print strftime(myTimeFmt,t)
}
set print
set xrange[0.5:31.5]
set xtics 1 scale 0 offset 0,0.5 font ",8"
set link x2 via x inverse x
set x2tics 1 out scale 0 offset 0,-0.5 font ",8"
set yrange [:] reverse noextend
set ytics 1 scale 0
set key noautotitle
set style fill solid 0.4 border lc "black"
WeekDay(t) = word("S M T W T F S",int(tm_wday(t))+1)
DayColor(t) = tm_wday(t) == 0 ? 0xff0000 : tm_wday(t) == 6 ? 0xffdd00 : 0xdddddd
MonthFirst(t) = int(strptime("%Y%m%d",sprintf("%04d%02d01",tm_year(t),tm_mon(t)+1)))
Month(t) = int(tm_year(t)*12 + tm_mon(t))
MonthName(n) = word("January February March April May June July August September October November December",n)
MonthLabel(t) = sprintf("%s",MonthName(Month(t)%12+1)) # without year
MonthLabel(t) = sprintf("%s %04d",MonthName(Month(t)%12+1),tm_year(t)) # alternatively with year
plot $Data u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(0.5):(0.5):(DayColor(t)): \
xtic(tm_mday(t)):ytic(MonthLabel(t)) w boxxy lc rgb var, \
'' u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(WeekDay(t)) w labels
pause -1
MonthOffset(t) = tm_wday(MonthFirst(t))==0 ? 7 : tm_wday(MonthFirst(t))
set xrange[1.5:*]
plot $Data u (t=timecolumn(1,myTimeFmt), tm_mday(t)+MonthOffset(t)):(Month(t)):(0.5):(0.5):(DayColor(t)): \
xtic(WeekDay(t)):x2tic(WeekDay(t)):ytic(MonthLabel(t)) w boxxy lc rgb var, \
'' u (t=timecolumn(1,myTimeFmt), tm_mday(t)+MonthOffset(t)):(Month(t)):(sprintf("%d",tm_mday(t))) w labels font ",8"
### end of code
结果: