Random Name
Random Name

Reputation: 41

Is there a way to have gnuplot use xaxis time data, but skip certain intervals (e.g. non-trading hours)

I'm collecting pricing data on stocks and options during trading hours and appending them to a data file that I plot with gnuplot. The file looks like:

2013-01-30--15:58:14 38.68 0.64
2013-01-30--15:58:44 38.70 0.64
2013-01-30--15:59:15 38.70 0.64
2013-01-30--15:59:45 38.69 0.64

I end up with large periods of time that I don't collect any data for since the markets are closed.

When I plot this data with gnuplot, using xdata as timefmt, it displays large gaps from the end of one day to the start of another.

I'd prefer to have it skip those times during the days where there is no actual data... Is there a way to do this?

I've been able to come close by not plotting the data against the time value in the first column, but I'd like to show the time data AS WELL AS skip those times when the data was not collected.

I hope this makes sense and appreciate your help.

Upvotes: 4

Views: 1480

Answers (2)

theozh
theozh

Reputation: 25724

There are similar but slightly different questions:

The question is not about breaking the axis, but skipping time intervals with no data. This can simply be done by plotting the y-data versus the row index (i.e. pseudocolumn 0) (check pseudocolumns), however, then the challenge is to get some reasonable xtics. Here are two suggestions.

Script: (works for gnuplot>=5.0.0, Jan. 2015)

### skip non-trading hours
reset session

FILE = "SO14618708.dat"
myTimeFmt = "%Y-%m-%d--%H:%M:%S"

# create some random test data
set print FILE
    t0 = time(0)
    y0 = 100
    do for [i=0:400] {
        t = t0 + i*1800
        isOpen(t) = tm_wday(t)>0 && tm_wday(t)<6 && tm_hour(t)>=9 && tm_hour(t)<=17
        if (isOpen(t)) {
            print sprintf("%s %g",strftime(myTimeFmt,t),y0=y0+rand(0)*2-1)
        }
    }
set print

set format x "%a\n%d" timedate
set grid x,y
set ytics 5
set key noautotitle

set multiplot layout 3,1

    set title "with non-trading hours"
    plot FILE u (timecolumn(1,myTimeFmt)):2 w l lc "red"
    
    set title "without non-trading hours, but possible duplicates in day tics"
    set format x "\n" timedate 
    myXtic(col) = strftime("%a\n%d",strptime(myTimeFmt,strcol(col)))
    N = 15
    plot FILE u 0:2 w l lc "web-green", \
           '' u ($0*N):(NaN):xtic(myXtic(1)) every N

    N = 1
    set title sprintf("with tics only every Nth day (here: N=%d)",N)
    SecPerDay = 3600*24
    isNewDay(col)       = (t0=t1,t1=timecolumn(col,myTimeFmt),t0!=t0 || int(t1)/SecPerDay-int(t0)/SecPerDay>0)
    everyNthNewDay(col) = (isNewDay(col) ? d0=d0+1 : 0, d0==N ? (d0=0,1) : 0)
    myXtic(col)         = everyNthNewDay(col) ?  strftime("%a\n%d",t1) : NaN
    plot FILE u 0:2 w l lc "blue", \
         t1=(d0=0,NaN) '' u 0:(NaN):xtic(myXtic(1))
    
unset multiplot
### end of script

Result:

enter image description here

Script: (version for the time of OP's question. Works for gnuplot>=4.6.0, March 2012)

Creation of reasonable time and string data files is difficult in gnuplot 4.6, so this part was skipped and assumed you have a suitable datafile. Although, in the lowest plot, I've only managed either to not display the very first tic (Thu 22) or to show it incorrectly.

### skip non-trading hours
reset

FILE = "SO14618708.dat"
myTimeFmt = "%Y-%m-%d--%H:%M:%S"

set format x "%a\n%d"
set grid x,y
set ytics 5
set key noautotitle
set timefmt "%Y-%m-%d--%H:%M:%S"
set xdata time

set multiplot layout 3,1

    set title "with non-trading hours"
    plot FILE u (timecolumn(1)):2 w l lc rgb "red"
    
    set title "without non-trading hours, but possible duplicates in day tics"
    set format x "\n" 
    myXtic(col) = strftime("%a\n%d",strptime(myTimeFmt,strcol(col)))
    N = 15
    plot FILE u 0:2 w l lc rgb "web-green", \
           '' u ($0*N):(NaN):xtic(myXtic(1)) every N

    N = 1
    set title sprintf("with tics only every Nth day (here: N=%d)",N)
    SecPerDay = 3600*24
    isNewDay(col)       = (t0=t1,t1=strptime(myTimeFmt,strcol(col)),(t0!=t0) || ((int(t1)/SecPerDay-int(t0)/SecPerDay)>0))
    everyNthNewDay(col) = (isNewDay(col) ? d0=d0+1 : 0, d0==N ? (d0=0,1) : 0)
    myXtic(c)           = c ?  strftime("%a\n%d",t1) : ' '
    plot FILE u 0:2 w l lc rgb "blue", \
         t1=(d0=0,NaN) '' u ((c=everyNthNewDay(1)) ? $0 : NaN):(NaN):xtic(myXtic(c)) w p
unset multiplot
### end of script

Result: (created with gnuplot4.6.0)

enter image description here

Upvotes: 0

lev.tuby
lev.tuby

Reputation: 477

If I understood correctly, you can make good use of a broken axis on x.

There are two ways to obtain broken axis. The first one relies on ternary operators to plot the data only in the region of your interest, which in your case should not even be necessary, and shifting the xtics left in order to reduce the dimension of the empty region. This is a nice tutorial:

http://gnuplot-tricks.blogspot.com/2009/06/broken-axis-revisited.html

The second one makes uses of multiplots instead. This is probably better suit to your needs.

http://gnuplot-tricks.blogspot.com/2010/06/broken-axis-once-more.html

Hope it helps.

Upvotes: 3

Related Questions