gnuplot - set xrange with date [1:31]

212 Views Asked by At

Hej!

My automatized script is running through many month. I'd like to have the monthly plots to show always the window [1:31], actually YYYY-MM-01 to YYYY-MM-31. For all month my script is handling. (And I don't care that some month have no data at the ends, e.g., February.)

Unfortunately, I don't know how to provide the range to gnuplot correctly. Since data is time, sth like [1:31] doesn't work of course. But neither can I explicitly state the full date in my script since next month will be different again.

Any ideas? Thanks!

EDIT: I edited the original post to include some more information. Sorry for not including it right away.

  • DATA: My data basically looks like this (with many more lines in between). I have a separate datafile per month, starting on the 1st, 0 AM, towards the 31st, 12 PM:
2022-07-01,00:00:16,27.3,3,28.0,9.0,995.6
2022-07-01,00:05:16,27.3,3,28.0,9.0,995.5
2022-07-01,00:10:16,27.3,3,28.0,9.0,995.4
2022-07-01,00:15:16,27.3,3,28.0,9.0,995.3
2022-07-01,00:20:16,27.3,3,28.0,9.0,995.3
2022-07-01,00:25:16,27.3,3,28.0,9.0,995.3
...
2022-07-31,23:54:16,27.1,3,27.9,12.1,994.9
2022-07-31,23:55:16,27.1,3,27.9,12.1,994.9
2022-07-31,23:56:16,27.1,3,27.9,12.1,995.1
2022-07-31,23:57:16,27.1,3,27.9,11.9,995.0
2022-07-31,23:58:16,27.1,3,27.9,11.9,995.0
  • EXAMPLE IMAGE: An example (for the month of July) is attached. As I'm not allowed to have embedded images, see the link: Example plot for July

  • CODE EXAMPLE: The following code is used to modify the x-axis. A very basic attempt (set xrange ["01":"31"]) is included to set the range between 1 and 31. But since xdata is not integers, this is a failed attempt of course.

set xdata time
set timefmt '%Y-%m-%d,%H:%M:%S'
set format x "%d"
#set xrange ["01":"31"]
set xtics 21600*4*7
set mxtics 7
set grid xtics
set grid mxtics

Of course, the xdata changes from month to month. But I'd like to have the day of the month only, not the full date. And, like I said, fixed to 1-31 for easier comparison between months.

2

There are 2 best solutions below

1
On BEST ANSWER

It's not fully clear to me how you want specify the month which you want to plot. Maybe we get a step further with the following example.

Check help tm_year, help tm_mon, help strftime, help strptime, help time_specifiers. Note, that tm_mon() will return a month index from 0 to 11, not from 1 to 12.

The script sets the range from the first of a given month to the first of the next month. If you give more information about your actual task, we could also put the plots into a loop to loop several months.

Script:

### select only a month from time data
reset session

myTimeFmt = "%Y-%m-%d"

# create some random test data
set table $Data
    set samples 365
    d0 = strptime(myTimeFmt,"2022-01-01")
    plot '+' u (strftime("%Y-%m-%d",d0+$0*24*3600)):(rand(0)*10) w table
unset table

t0(m)        = strptime("%Y-%m",m)
t1(m)        = (t=strptime("%Y-%m",m),strptime("%Y-%m",sprintf("%04d-%02d",tm_year(t),tm_mon(t)+2)))
monthName(m) = strftime("%B %Y",strptime("%Y-%m",m))

set format x "%1d" timedate
set grid x,y
set xtic 24*3600
set key noautotitle

set multiplot layout 3,1

    myMonth = "2022-01"
    set xrange[t0(myMonth):t1(myMonth)]
    set title monthName(myMonth)
    plot $Data u (timecolumn(1,myTimeFmt)):2 w l 

    myMonth = "2022-02"
    set xrange[t0(myMonth):t1(myMonth)]
    set title monthName(myMonth)
    plot $Data u (timecolumn(1,myTimeFmt)):2 w l

    myMonth = "2022-09"
    set xrange[t0(myMonth):t1(myMonth)]
    set title monthName(myMonth)
    plot $Data u (timecolumn(1,myTimeFmt)):2 w l

unset multiplot
### end of script

Result:

enter image description here

Addition:

Now, that you showed your data, I noticed that your date and your time are in different columns. That's why it's important to always add data or describe the format in detail.

Here is a suggestion where the graphs always span 31 days, but the xtics and labels are suppressed for the shorter months. Admittedly, it's not straightforward and maybe not so easy to understand. So, you can try to improve your gnuplot skills.

Script:

### select only a month from time data
reset session

myMonth = "2022-02"

# create some random test data
set table $Data separator comma
    t0(m) = strptime("%Y-%m",m)
    t1(m) = (t=strptime("%Y-%m",m),strptime("%Y-%m",sprintf("%04d-%02d",tm_year(t),tm_mon(t)+2)))
    set xrange[t0(myMonth):t1(myMonth)-1]
    set samples 100
    plot '+' u (strftime("%Y-%m-%d",$1)):(strftime("%H:%M:%S",$1)):(rand(0)+18):(rand(0)+20):(rand(0)+22) w table
unset table

myDay(col)   = tm_mday(timecolumn(1,"%Y-%m-%d"))
myTime(col)  = timecolumn(2,"%H:%M:%S")/24./3600.
monthName(m) = strftime("%B %Y",strptime("%Y-%m",m))

set datafile separator comma
set ytic 1
set grid x,y
set key noautotitle
set title monthName(myMonth)
set xrange[1:32]

plot for [col=3:5] $Data u (d0=myDay(1), d0+myTime(2)):col w l lc col-2, \
        '+' u (t0=$0+1):(0):xtic(t0==d0+1?'':sprintf("%d",t0)) every ::::d0 w p ps 0 noautoscale
### end of script

Result: (for January, February and September)

enter image description here

enter image description here

enter image description here

2
On

@theozh

I had a look as your code, and, actually, the part concerning my original question was not as complicated as I thought. I am using the following code:

t0(m) = strptime("%Y-%m",m)
#t1(m) = (t=strptime("%Y-%m",m),strptime("%Y-%m",sprintf("%04d-%02d",tm_year(t),tm_mon(t)+2)))
t1(m) = t0(m)+31*24*3600
set xrange[t0(myMonth):t1(myMonth)]

The results are as follows for July and September:

enter image description here enter image description here

The only thing that "remains" would be to set all months in the range 1-31, but that's cosmetics and not really necessary. It works pretty well as it is - and it fits my script so that the automation is working as well!

NICE!