Search code examples
gnuplotdatetime-format

Gnuplot - How do not plot a piece of line for non-contiguous date/time


I'm trying to plot last 24 hours from datafile. This data file has date/time and value

Below are the contents of datafile.dat:

2015-12-17-21:07:41,74.30
2015-12-17-21:08:41,74.10
2015-12-17-21:08:41,74.10
2015-12-30-21:08:41,79.10
2015-12-30-21:09:41,79.10
....

below gnuplot script

set datafile separator ","
set terminal png font arial 12 size 1000,600
set xdata time
set timefmt "%Y-%m-%d-%H:%M:%S"
set format x "%d/%m\n%H:%Mh"
set xrange [ time(0) - 86400 : time(0) ]    # 86400 sec = 1 day 
set grid
set output "/data/weather/humidity.png"
plot "datafile.dat" using 1:2 with lines smooth bezier title "" 

As I don't have data in the file for day 29, why does gnuplot draw a line from day 29 to day 30? I don't have rows in the data file for day 29, and I'd like to not draw them. If I don't have 24 hours of data in the the file, I would like to draw just what I have.

How can I do that?


Solution

  • Gnuplot has an option set clip which controls how lines connecting to points outside the given range are drawn: set clip one, which is the default, draws lines between two points if one of the points is in-range. The line is clipped at the plot border. set clip two would plot line parts even if both points are out-range, but the line goes through the plot area.

    Use unset clip to plot only lines between points which are both in-range.

    set datafile separator ","
    set xdata time
    set timefmt "%Y-%m-%d-%H:%M:%S"
    set format x "%d/%m\n%H:%Mh"
    set xrange [ time(0) - 86400 : time(0) ]
    unset clip
    plot "datafile.dat" using 1:2 with lines title "" 
    

    Unfortunately, that doesn't work properly with smoothing, because gnuplot first does the smoothing between all points (in-range and out-range), and then only applies the clipping rules. In order to have the smoothing handles properly you must filter the points before handling them to gnuplot, e.g. with awk:

    set datafile separator ","
    set xdata time
    set timefmt "%Y-%m-%d-%H:%M:%S"
    set format x "%d/%m\n%H:%Mh"
    set xrange [time(0) - 86400 : time(0)]
    
    filter = '< awk -F, -v d="$(date -d''24 hours ago'' +''%F-%T'')" ''$1>=d'' datafile.dat'
    plot filter using 1:2 with lines smooth bezier title "" 
    

    Note, that the comparison $1 >= d in awk is a string comparison, but that is fine for the time format you are using.