在时间序列图中指示周末并在时间序列 gnuplot 中设置 xrange

发布于 2025-01-10 04:43:20 字数 1280 浏览 0 评论 0原文

使用优秀的答案 gnuplot - Read Double Quoted datetime stamp 我已经能够绘制我的时间序列数据。

我现在尝试指示周末(或有趣的时间块)我的情节并将可见 xrange 设置为 31/1 到 28/2

今年 2 月的周末是 2/5/22 到 2/6/22 和 2/12/22 到2/13/22 等 - 我如何绘制垂直柱和阴影来指示周末或其他有趣的时间序列块?我尝试使用时间序列点(即周末1)绘制一个矩形,但我无法填充该形状。然后我尝试绘制一个矩形,但无法弄清楚如何以时间序列格式指定角点来显示它。

由于我的 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"

Using the excellent answer gnuplot - Read Double Quoted datetime stamp I have been able to plot my time series data.

I now trying to indicate weekends (or interesting timeblocks) my plot and set visible xrange to be 31/1 to 28/2

Weekends in Feb this year were 2/5/22 to 2/6/22 and 2/12/22 to 2/13/22 etc - how could I draw a vertical column and shade to indicate weekend or other interesting timeseries blocks? I looked at trying to plot a rectangle using timeseries points, ie weekend1, but I was unable to fill that shape. Then I tried to draw a rectangle, but could not work out how to specify the corners in the timeseries format to display it.

Since my x axis is a timeseries

  • How could I indicate all weekends in the diagram - kind of like in a calendar or timesheet?
  • How do I define the xrange to be 1/31/22 to 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"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

任性一次 2025-01-17 04:43:20

这是我从你的问题中了解到的:绘制一些时间序列数据并通过为背景着色来突出显示周末。
实现此目的的一种可能方法是创建包含时间范围内所有日期的数据块,并绘制带有颜色的框(检查 help boxxyerror)(检查 help lc 变量),具体取决于工作日(查看 help tm_wday)。

  • 首先,您必须在背景中绘制方框,然后
  • 背景颜色的数据应跨越整个垂直图形大小。为此,您需要知道数据的 y 范围。您可以从 stats 获取 STATS_minSTATS_max(查看help stats)。
  • 为了跨越整个图表,您可以扩展框的 y 范围(通过在顶部和底部再次添加范围),但不要对框应用自动缩放(请检查 help noautoscale)。自动缩放将仅用于数据。
  • 也许您有一个固定的已知 y 范围,那么您可以简单地通过 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

结果:

在此处输入图像描述

注意: 首先我以为您想绘制一个突出显示周末的日历,但是这个不是你的问题。由于我已经有了以下代码(它将绘制两个不同版本的日历),所以我仍然会发布它。也许它对您或其他人进一步的适应和优化有用。

脚本:

### plot a calendar
reset session

myTimeFmt  = "%d.%m.%Y"
DateStart  = "01.01.2022"
DateEnd    = "31.12.2022"
SecsPerDay = 24*3600

set print $Calendar
    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)      = strftime("%a",t)[1:1]
DayColor(t)     = tm_wday(t) == 0 ? 0xff0000 : tm_wday(t) == 6 ? 0xffdd00 : 0xdddddd
Month(t)        = int(tm_year(t)*12 + tm_mon(t))
MonthLabel(t,y) = strftime( y ? "%B %Y" : "%Y", t)   # y=0 only month, y=1 month+year

plot $Calendar u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(0.5):(0.5):(DayColor(t)): \
             xtic(tm_mday(t)):ytic(MonthLabel(t,1)) w boxxy lc rgb var, \
        '' u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(WeekDay(t)) w labels

pause -1

MonthFirst(t)  = int(strptime("%Y%m%d",sprintf("%04d%02d01",tm_year(t),tm_mon(t)+1)))
MonthOffset(t) = tm_wday(MonthFirst(t))==0 ? 7 : tm_wday(MonthFirst(t))
set xrange[*:*]

plot $Calendar 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,1)) 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 script

结果:

在此处输入图像描述

在此处输入图像描述

添加:(带有事件的日历数据文件/数据块)

脚本:

### plot a calendar with events
reset session

myTimeFmt  = "%d.%m.%Y"
DateStart  = "01.01.2022"
DateEnd    = "31.12.2022"
SecsPerDay = 24*3600

set print $Calendar
    do for [t=strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd):SecsPerDay] {
        print strftime(myTimeFmt,t)
    }
set print

$Events <<EOD
01.01.2022   A   0xff0000
23.04.2022   B   0x00ff00
03.06.2022   C   0x0000ff
12.08.2022   A   0xffff00
05.09.2022   B   0xff00ff
10.10.2022   X   0x00ffff
12.02.2022   Y   0xffa500
EOD

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"

Month(t)        = int(tm_year(t)*12 + tm_mon(t))
MonthLabel(t,y) = strftime( y ? "%B %Y" : "%Y", t)   # y=0 only month, y=1 month+year

plot $Calendar u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(0.5):(0.5): \
             xtic(tm_mday(t)):ytic(MonthLabel(t,1)) w boxxy lc "light-grey", \
     $Events u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(0.5):(0.5):3 w boxxy lc rgb var, \
          '' u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):2 w labels
### end of script

结果:

在此处输入图像描述

Here is what I've understood from your question: plot some time series data and highlight the weekends by coloring the background.
One possible way to get this would be to create datablock with all days within your time range and draw boxes (check help boxxyerror) which are colored (check help lc variable) depending of the weekday (check help tm_wday).

  • first you have to plot the boxes in the background and then the data
  • the background color should span the whole vertical graph size. For this you need to know the y-range of the data. You can get STATS_min and STATS_max from stats (check help stats).
  • in order to span the whole graph you can extend the y-range of the boxes (by adding the range again on top and on bottom) but do not apply autoscale for the boxes (check help noautoscale). Autoscale will be only used for the data.
  • Maybe you have a fixed known y-range, then you can simply set it via set yrange and suitable size of the boxes.

I hope you can adapt the following example to your needs.

Script:

### 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

Result:

enter image description here

NB: first I thought you wanted to plot a calendar highlighting the weekends, but this was not your question. Since I already had the following code (which will plot a calendar in two different versions), I will post it nevertheless. Maybe it is useful to you or others for further adaptions and optimizations.

Script:

### plot a calendar
reset session

myTimeFmt  = "%d.%m.%Y"
DateStart  = "01.01.2022"
DateEnd    = "31.12.2022"
SecsPerDay = 24*3600

set print $Calendar
    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)      = strftime("%a",t)[1:1]
DayColor(t)     = tm_wday(t) == 0 ? 0xff0000 : tm_wday(t) == 6 ? 0xffdd00 : 0xdddddd
Month(t)        = int(tm_year(t)*12 + tm_mon(t))
MonthLabel(t,y) = strftime( y ? "%B %Y" : "%Y", t)   # y=0 only month, y=1 month+year

plot $Calendar u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(0.5):(0.5):(DayColor(t)): \
             xtic(tm_mday(t)):ytic(MonthLabel(t,1)) w boxxy lc rgb var, \
        '' u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(WeekDay(t)) w labels

pause -1

MonthFirst(t)  = int(strptime("%Y%m%d",sprintf("%04d%02d01",tm_year(t),tm_mon(t)+1)))
MonthOffset(t) = tm_wday(MonthFirst(t))==0 ? 7 : tm_wday(MonthFirst(t))
set xrange[*:*]

plot $Calendar 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,1)) 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 script

Result:

enter image description here

enter image description here

Addition: (calendar with events from a datafile/datablock)

Script:

### plot a calendar with events
reset session

myTimeFmt  = "%d.%m.%Y"
DateStart  = "01.01.2022"
DateEnd    = "31.12.2022"
SecsPerDay = 24*3600

set print $Calendar
    do for [t=strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd):SecsPerDay] {
        print strftime(myTimeFmt,t)
    }
set print

$Events <<EOD
01.01.2022   A   0xff0000
23.04.2022   B   0x00ff00
03.06.2022   C   0x0000ff
12.08.2022   A   0xffff00
05.09.2022   B   0xff00ff
10.10.2022   X   0x00ffff
12.02.2022   Y   0xffa500
EOD

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"

Month(t)        = int(tm_year(t)*12 + tm_mon(t))
MonthLabel(t,y) = strftime( y ? "%B %Y" : "%Y", t)   # y=0 only month, y=1 month+year

plot $Calendar u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(0.5):(0.5): \
             xtic(tm_mday(t)):ytic(MonthLabel(t,1)) w boxxy lc "light-grey", \
     $Events u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):(0.5):(0.5):3 w boxxy lc rgb var, \
          '' u (t=timecolumn(1,myTimeFmt), tm_mday(t)):(Month(t)):2 w labels
### end of script

Result:

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文