5

I'm plotting some [date, value] formatted data (cpu use over time) and want the xtics to start at 0 or 1 instead of the first date.

So for 10 hours it should look like: 0:01:00, 0:02:00, .., 0:10:00 insead of 9:23:00 ... (since the first day in the data is the 9th at 11pm).

My current datetime settings:

set xdata time
set timefmt "%Y-%m-%d %H:%M:%S"
set xtics format "%d:%H:%M" font ",25"

Edit: If there's a way to just count hours starting from 0 on the x axis without day info that'd be awesome too. Either way. I just want to start counting from 0 to make the "time taken" very clear.

CornSmith
  • 1,957
  • 1
  • 19
  • 35
  • 1
    I played around a bit with various settings, but I couldn't get it to work. The problem arises when you use `%d`, which is 'day of the month', but not the number of days. So the minimum is always `1`, and your output would start with `01:...` at the `0`-position. I have no idea how to bypass this. – Christoph Sep 16 '13 at 18:48
  • Well, I'd be perfectly happy to even omit the day as long as x axis could have the total hours. I'll edit my answer to add that info. – CornSmith Sep 16 '13 at 19:15

2 Answers2

2

I couldn't get it to work with set xdata time, because for the output only the day of the month is available, which is in the range [1:31], so the 0-position would start with 1. The same happens for total number of hours, because that value is limited to [0:23], so that number over 23 are wrapped back.

Here is a solution without time data. I use the strptime function to convert the date string to a time stamp (in seconds), which is then divided by 3600 to get the hour (as float number):

The test data file is:

2013-08-25 18:45:11 100
2013-08-25 19:11:23 200
2013-08-25 20:00:32 400
2013-08-25 21:00:32 300
2013-08-26 20:11:12 500

And the example script:

reset
file='data.txt'
fmt="%Y-%m-%d %H:%M:%S"
start=system('head -1 '.file)
start_stamp = strptime(fmt, start)
plot 'data.txt' using ((strptime(fmt, stringcolumn(1).' '.stringcolumn(2))-start_stamp)/3600.0):3 with lines t ''

The first column is extracted with an external tool.

The result is:

enter image description here

And here is another variant, which uses a more comfortable data format, using commas as separators, and the first column is extracted with gnuplot:

The data file:

2013-08-25 18:45:11,100
2013-08-25 19:11:23,200
2013-08-25 20:00:32,400
2013-08-25 21:00:32,300
2013-08-26 20:11:12,500

The script file:

reset
file='data.txt'
fmt="%Y-%m-%d %H:%M:%S"
set datafile separator ','
plot 'data.txt' using ($0 == 0 ? start_stamp = strptime(fmt, stringcolumn(1)) : 0, \
     (strptime(fmt, stringcolumn(1))-start_stamp)/3600.0):2 with lines t ''

The results are equivalent.

EDIT: One last variant, which is a mixture @andyras's and my answer. You can use set timefmt with an explicit call to timecolumn to parse the input as time. The output is then handled like a conventional double number. I use $0, i.e. the number of the current sample, to set the offset value:

reset
set timefmt "%Y-%m-%d %H:%M:%S"

offset = 0
t0(x)=(offset=($0==0) ? x : offset, x - offset)

plot 'data.txt' u (t0(timecolumn(1))/3600.0):3 notitle w l
Christoph
  • 47,569
  • 8
  • 87
  • 187
  • Could you explain what the pseudocolumn $0 is doing in this case? – CornSmith Sep 16 '13 at 23:16
  • 2
    @CornSmith See the last script in the edited answer. `$0` is the index of the current row, `$0 == 0` is `true` in the first row. – Christoph Sep 17 '13 at 08:25
  • Your last variant is brilliant! I had no idea you could even do functions in a gnuplot script. – CornSmith Sep 17 '13 at 16:16
  • Excellent answers--I wanted to do something very much like this (except dividing by 86400.0 to get the absolute number of days), but I could not figure out how to get it into the desired "%d:%H:%M" format with a number of days > 31. – andyras Sep 17 '13 at 17:45
  • @andyras When browsing a bit through the documentation I found the `timecolumn` function, but it is almost not documented. And about `set timefmt` the documentation says, that it requires `set xdata time`. Tested a bit to find out how they match together... – Christoph Sep 17 '13 at 19:46
1

This is not quite an answer, but close enough that I am posting it as such.

I have a way that you can start the time file at time zero (inspired by this answer to an old question of mine):

set xdata time
set timefmt "%Y-%m-%d %H:%M:%S"
set xtics format "%d:%H:%M" font ",6"

first = 0
offset = 0
# returns data offset by first value
t0(x)=(offset=(first==0)?x:offset,first=1,x-offset)

plot 'data.dat' u (t0(timecolumn(1))):3 notitle

Here are some sample data

2013-09-16 00:14:00 1
2013-09-26 00:15:00 3
2013-10-04 00:16:00 2
2013-10-19 00:17:00 4

and the output:

enter image description here

This strategy has the problem that once the data go above 31 days the date counter resets.

I could not figure out how to get the xtics format to manipulate data columns.

Community
  • 1
  • 1
andyras
  • 15,542
  • 6
  • 55
  • 77
  • This is also a very good answer. I'll use this for data that spans 3+ days, and Cristoph's for the rest. I wish I could mark both as correct. For data >31 days I'll use Cristoph's answer altered for days only instead of hours. – CornSmith Sep 16 '13 at 21:39