Gnuplot multiple values in ytics

Viewed 143

I'm trying to display values in the ytics of a simple lines points graph in two different representations, in days and years.

My data file consists of two cols, each of which containing unix timestamps.

1580342400  1492387200
1583107200  1493856000
1584230400  1494201600
1585267200  1495238400
...

Here's what I did so far:

set term qt
set xlabel "Current Date"
set ylabel "Time to wait in days and years"
set timefmt "%s"
set format x "%d.%m.\n%Y"
set xdata time
set grid

plot 'times.log' \
  u 1:(($1-$2)/86400)::yticlabels(sprintf("%d (%.1f)",(($1-$2)/86400),(($1-$2)/86400/365))) \
  with lp lw 2 lt 4 notitle

Which yields the following result: gnuplot-tics

The only thing that really bugs me is that the ytics are not distributed equidistantly.

Is there any way to have my desired format and still remain equidistant ytics?

Another option that crossed my mind was using the new stats function together with a for loop iterating over all data sets and adding one tic label for each data set manually.

Any hint welcome, however, I'm not a big fan of perl/bash/etc. mixed with gnuplot, I'd like to keep it gnuplot only in this case.

1 Answers

One possible way would be the following: take y-axis for the days and y2-axis for the years. You have to link them, check help link. If you want the years also on the left side at the y-axis you can "cheat" e.g. with set y2tics offset graph -1.105,0. You have to play with all the offsets and margins to get an optimum result. I am not aware that there would be a simple automated solution with something like set format y "%tD (%tY)" time (actually, %tY is not a valid format specifier). Check help format specifiers and help time_specifiers. Keep in mind that although the numbers for days will be equidistant, but the numbers of years won't because of rounding errors.

Code:

### days and years at the y-axis
reset session

DateStart = "01.01.2020"
DateEnd   = "01.10.2021"

myTimeFmt = "%d.%m.%Y"
set xrange[strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd)]

# create some test data
set samples 20
set table $Data
    plot '+' u 1:($1*1.07+rand(0)*3*86400) w table
unset table

set lmargin 14
set xlabel "Current date"
set format x "%d.%m.\n%Y" time

set ylabel "Time to wait in days (years)" offset -5,0
set format y "%.0f"
set ytics offset -5,0

set link y2 via y/365.25 inverse y*365.25
set y2tics
set y2tics offset graph -1.105,0
set format y2 "(%0.2f)"
set grid x,y
set key noautotitle

plot $Data u 1:(($2-$1)/3600/24) w lp pt 7

### end of code

Result:

enter image description here

Addition:

Days on y-axis and years on y2-axis offers the advantage to set the y2tics steps "independently" with even numbers, but of course, the grid will only fit to the y-axis. Furthermore, you don't have to fiddle around with offsets. Of course, you have to link the axis (check help link).

Concerning test data, you can plot or print into a table, check help table and help set print. Like you, I prefer to do everything (if possible) in gnuplot, however, sometimes it might get pretty complicated and lengthy. Furthermore, when I post an answer on SO, I always try to give a "copy & paste & run" example. If I don't have enough OP's data, I typically include a generation of some (random) data which resembles the OP's data in order to get a reasonable looking demo graph. In your case, simply skip these test data lines and replace $Data in the plot command with your filename, in your case 'times.log'.

Code:

### days at y-axis and years at y2-axis
reset session

DateStart = "01.01.2020"
DateEnd   = "01.10.2021"

myTimeFmt = "%d.%m.%Y"
set xrange[strptime(myTimeFmt,DateStart):strptime(myTimeFmt,DateEnd)]

# create some test data
set samples 20
set table $Data
    plot '+' u 1:($1*1.07+rand(0)*3*86400) w table
unset table

set xlabel "Current date"
set format x "%d.%m.\n%Y" time

set ylabel "Time to wait in days"
set format y "%.0f"
set ytics nomirror

set link y2 via y/365.25 inverse y*365.25
set y2label "Time to wait in years"
set y2tics 0.02
set format y2 "%0.2f"
set grid x,y
set key noautotitle

plot $Data u 1:(($2-$1)/3600/24) w lp pt 7
### end of code

Result:

enter image description here

Related