Plotting trajectory with gnuplot - gnuplot

I have a datafile with position of a moving point in the following format.
x1 y1
x2 y2
x3 y3
.
.
.
I wish to make an animated trajectory with this data in gnuplot. How can I do that?
I tried
do for [i=1:20] {
plot "temp.dat" every ::i using 1 : 2 w p
}
But it plots all the points in a single image, not an animation. What is the way of doing this?

While I was coding and got interrupted... #Ethan's answer already contains all the necessary ingredients, I post my answer nevertheless, with a little visual demo...
Check help gif, help stats and help every, these are the main "components".
In the following example you hopefully find what you are looking for.
Code:
### trajectory animated
reset session
# create some test data
v = 40
a = 45
g = 9.81
set print $Data
do for [i=0:86] {
t = i/10.
sx(t) = v*cos(a)*t
sy(t) = v*sin(a)*t - 0.5*g*t**2
print sprintf("%.3f %.3f",sx(t),sy(t))
}
set print
set xrange[0:200]
set yrange[0:80]
set term gif size 400,300 animate delay 5 optimize
set output "Trajectory.gif"
stats $Data nooutput
N = STATS_records
do for [i=0:N-1] {
plot $Data u 1:2 every ::::i w l notitle, \
'' u 1:2 every ::i::i w p pt 7 lc rgb "red" notitle
}
set output
### end of code
Result:

If you just want the animation to show on the screen, then your code is fine except that you need to add a delay between the successive frames:
do for [i=1:20] {
plot "temp.dat" every ::i using 1 : 2 w p
pause 0.1 # 1/10 second between frames
}
If you are making an animated gif file then the pause doesn't go into the loop itself, it becomes a parameter to the set term command:
set term gif animate delay 10 # 10 = 10 units of 0.01 seconds
set output 'animation.gif'
do for [i=1:20] {
plot "temp.dat" every ::i using 1 : 2 w p
}

Related

Stacking curves on plot/graph/canvas iteratively

With a set of data files. I would like to performs series of operations on each file (such as fitting) and stack the resulting curves continiously along with my analysis (to see how each curves fit on the bigger picture). I wrote the following code snippet
reset
PATH = 'XRP_'
nmin = 1
nmax = 20
f(x) = log10(x); h(x) = a*x + b
name(i) = sprintf(PATH.'%04d/data_main_ddnls_twod_mlce.dat', i)
set xrange [0:7]
start = 0
set fit
do for [i=nmin:nmax]{
fit [4:] h(x) name(i) using (f($1)):(f($4)) via a, b
if (start==0){
plot name(i) using (f($1)):(f($4)) w l title sprintf("%04d", i)
} else {
replot name(i) using (f($1)):(f($4)) w l title sprintf("%04d", i)
}
start = start + 1
pause -1
}
# Add the slope
replot (1./5.)*x + 0.5 lc 'black' lw 3 dt 2
unset fit
# pause -1
Instead of stacking all the previous curves + the current one, it plots only the current curve i-times (see loop of code). For instance, after 10 iterations it plots only the 10th datafile, 10 times (see legends on picture)
How can I fix this?
The reason your plot behaves the way it does, and example (1) from theozh does also, is that "replot f(x)" acts by tacking ", f(x)" onto the end of the previous plot command. By putting it in a loop you are basically creating the successive commands
plot f(x,i)
plot f(x,i), f(x,i)
plot f(x,i), f(x,i), f(x,i)
...
Yes the value of i might change each time, but nevertheless each plot command produces multiple copies of the same thing.
Alternative solution: I don't normally recommend multiplot mode for creating a single output, but in this case it may be the best option.
# force identical margins even if the range changes
set margins screen 0.1, screen 0.9, screen 0.1, screen 0.9
# ... same prelimary stuff as shown in the question
# revised loop using multiplot rather than replot
set multiplot
do for [i=nmin:nmax]{
fit [4:] h(x) name(i) using (f($1)):(f($4)) via a, b
plot name(i) using (f($1)):(f($4)) w l \
title sprintf("%04d", i) at screen 0.9, screen 1.0 - 0.02*i
unset tics
}
unset multiplot
Note that you cannot use auto-generated title placement because each of the multiplot iterations will put the title in the same place. So instead we use the form "title foo at ". Similarly it is better to turn off tic generation after the first pass so that you don't redraw the tics and labels each time through the loop.
Indeed, a strange behaviour which I also would not have expected. See the minimal examples below.
Version 1: basically your attempt. Not the expected result. I also don't know
why.
Version 2: the expected result. Basically the same but not in a loop.
Version 3: the expected result, although in a loop but using eval.
Not very satisfying but at least some solution. Hopefully, others will have better solutions or explanations.
### plotting in a loop
reset session
set colorsequence classic
# Version 1
set title "Version 1"
do for [i=1:5] {
if (i==1) { plot x**i }
else { replot x**i noautoscale }
}
pause -1
# Version 2
set title "Version 2"
plot x**1
replot x**2 noautoscale
replot x**3 noautoscale
replot x**4 noautoscale
replot x**5 noautoscale
pause -1
# Version 3
set title "Version 3"
do for [i=1:5] {
if (i==1) { cmd = sprintf("plot x**%d",i) }
else { cmd = sprintf("replot x**%d noautoscale",i) }
eval cmd
}
### end of code

Gnuplot: Scatter plot and density

I have x- and y-data points representing a star cluster. I want to visualize the density using Gnuplot and its scatter function with overlapping points.
I used the following commands:
set style fill transparent solid 0.04 noborder
set style circle radius 0.01
plot "data.dat" u 1:2 with circles lc rgb "red"
The result:
However I want something like that
Is that possible in Gnuplot? Any ideas?
(edit: revised and simplified)
Probably a much better way than my previous answer is the following:
For each data point check how many other data points are within a radius of R. You need to play with the value or R to get some reasonable graph.
Indexing the datalines requires gnuplot>=5.2.0 and the data in a datablock (without empty lines). You can either first plot your file into a datablock (check help table) or see here:
gnuplot: load datafile 1:1 into datablock
The time for creating this graph will increase with number of points O(N^2) because you have to check each point against all others. I'm not sure if there is a smarter and faster method. The example below with 1200 datapoints will take about 4 seconds on my laptop. You basically can apply the same principle for 3D.
Script: works with gnuplot>=5.2.0
### 2D density color plot
reset session
t1 = time(0.0)
# create some random rest data
set table $Data
set samples 700
plot '+' u (invnorm(rand(0))):(invnorm(rand(0))) w table
set samples 500
plot '+' u (invnorm(rand(0))+2):(invnorm(rand(0))+2) w table
unset table
print sprintf("Time data creation: %.3f s",(t0=t1,t1=time(0.0),t1-t0))
# for each datapoint: how many other datapoints are within radius R
R = 0.5 # Radius to check
Dist(x0,y0,x1,y1) = sqrt((x1-x0)**2 + (y1-y0)**2)
set print $Density
do for [i=1:|$Data|] {
x0 = real(word($Data[i],1))
y0 = real(word($Data[i],2))
c = 0
stats $Data u (Dist(x0,y0,$1,$2)<=R ? c=c+1 : 0) nooutput
d = c / (pi * R**2) # density: points per unit area
print sprintf("%g %g %d", x0, y0, d)
}
set print
print sprintf("Time density check: %.3f sec",(t0=t1,t1=time(0.0),t1-t0))
set size ratio -1 # same screen units for x and y
set palette rgb 33,13,10
plot $Density u 1:2:3 w p pt 7 lc palette z notitle
### end of script
Result:
Would it be an option to postprocess the image with imagemagick?
# convert into a gray scale image
convert source.png -colorspace gray -sigmoidal-contrast 10,50% gray.png
# build the gradient, the heights have to sum up to 256
convert -size 10x1 gradient:white-white white.png
convert -size 10x85 gradient:red-yellow \
gradient:yellow-lightgreen \
gradient:lightgreen-blue \
-append gradient.png
convert gradient.png white.png -append full-gradient.png
# finally convert the picture
convert gray.png full-gradient.png -clut target.png
I have not tried but I am quite sure that gnuplot can plot the gray scale image directly.
Here is the (rotated) gradient image:
This is the result:
Although this question is rather "old" and the problem might have been solved differently...
It's probably more for curiosity and fun than for practical purposes.
The following code implements a coloring according to the density of points using gnuplot only. On my older computer it takes a few minutes to plot 1000 points. I would be interested if this code can be improved especially in terms of speed (without using external tools).
It's a pity that gnuplot does not offer basic functionality like sorting, look-up tables, merging, transposing or other basic functions (I know... it's gnuPLOT... and not an analysis tool).
The code:
### density color plot 2D
reset session
# create some dummy datablock with some distribution
N = 1000
set table $Data
set samples N
plot '+' u (invnorm(rand(0))):(invnorm(rand(0))) w table
unset table
# end creating dummy data
stats $Data u 1:2 nooutput
XMin = STATS_min_x
XMax = STATS_max_x
YMin = STATS_min_y
YMax = STATS_max_y
XRange = XMax-XMin
YRange = YMax-YMin
XBinCount = 20
YBinCount = 20
BinNo(x,y) = floor((y-YMin)/YRange*YBinCount)*XBinCount + floor((x-XMin)/XRange*XBinCount)
# do the binning
set table $Bins
plot $Data u (BinNo($1,$2)):(1) smooth freq # with table
unset table
# prepare final data: BinNo, Sum, XPos, YPos
set print $FinalData
do for [i=0:N-1] {
set table $Data3
plot $Data u (BinNumber = BinNo($1,$2),$1):(XPos = $1,$1):(YPos = $2,$2) every ::i::i with table
plot [BinNumber:BinNumber+0.1] $Bins u (BinNumber == $1 ? (PointsInBin = $2,$2) : NaN) with table
print sprintf("%g\t%g\t%g\t%g", XPos, YPos, BinNumber, PointsInBin)
unset table
}
set print
# plot data
set multiplot layout 2,1
set rmargin at screen 0.85
plot $Data u 1:2 w p pt 7 lc rgb "#BBFF0000" t "Data"
set xrange restore # use same xrange as previous plot
set yrange restore
set palette rgbformulae 33,13,10
set colorbox
# draw the bin borders
do for [i=0:XBinCount] {
XBinPos = i/real(XBinCount)*XRange+XMin
set arrow from XBinPos,YMin to XBinPos,YMax nohead lc rgb "grey" dt 1
}
do for [i=0:YBinCount] {
YBinPos = i/real(YBinCount)*YRange+YMin
set arrow from XMin,YBinPos to XMax,YBinPos nohead lc rgb "grey" dt 1
}
plot $FinalData u 1:2:4 w p pt 7 ps 0.5 lc palette z t "Density plot"
unset multiplot
### end of code
The result:

How to draw a filledcurve graph with GNUPlot by using 2 csv files

If I have 2 csv files ("CSV1.csv" dataname_1 and "CSV2.csv" dataname_2), how can I draw filled curve graph from the data of 2 csv files. The formats of these CSV files are identical, where 2 is timestamps and 5 is the value thus the using 2:5
I am trying this:
plot dataname_2 using 2:5 title "Above" with filledcurves above lc rgb 'blue',\
dataname_1 using 2:5 title "Below" with filledcurves below lc rgb 'red',\
dataname_2 using 2:5 title "Engine Starts" with lines lc rgb "#1E90FF",\
dataname_1 using 2:5 title "Engine Hours" with lines lc rgb "#FF1493"
I need to modify the code above so that the output is:
A solution which will probably always work is to prepare the data with whatever external tool in such a way that gnuplot can handle and plot it. I'm aware that the philosophy of gnuplot is to concentrate on plotting and not necessarily on data preparation for plotting. However, it is always good to have a minimum set of features to do some basic data preparation.
In your case you have several problems, well, let's call it challenges ;-)
with filledcurves requires data within the same file or datablock
however, gnuplot cannot easily merge datafiles line by line (it can with some workaround, see: https://stackoverflow.com/a/61559658/7295599). Simply appending would be no problem with gnuplot.
the latter doesn't help you since with filledcurves needs identical x for upper and lower curve, i.e. x,y1,y2 and your data has x1,y1 and x2,y2
however, gnuplot cannot easily resample data (it can with some workaround, see: Resampling data with gnuplot)
with filledcurves cannot directly fill curves with non-monotonic increasing x (not the case with your data. Here just for illustration purposes) (it can with some workaround see: https://stackoverflow.com/a/53769446/7295599 or https://stackoverflow.com/a/56176717/7295599)
So a workaround for all this could be the following (works with gnuplot 5.2, maybe can be tweaked to work with earlier versions):
Assumptions:
Data x1,y1 and x2,y2 in two files or datablocks
Data has not necessarily identical x, i.e. x1,y1 and x2,y2
Data may contain non-monotonic x
the two curves have only one intersection (well, the workaround below will just take the first one)
Procedure:
if not already, get the data into a datablock.
Find the intersection of the curves.
Create new datablocks: Filled1 using Data1 from the beginning to the intersection point and using Data2 backwards from the intersection point to the beginning. Filled2 using Data1 from the end backwards to the intersection point and using Data2 from the intersection point to the end.
Plot $Data1 and $Data2 with lines and $Filled1 and $Filled2 with filledcurves
Steps 2 and 3, probably will not be much shorter in another programming language unless there are dedicated functions.
Get files to datablock: (see also here gnuplot: load datafile 1:1 into datablock)
# get files to datablocks
set table $Data1
plot 'myFile1.dat' u 1:2 w table
set table $Data2
plot 'myFile2.dat' u 1:2 w table
unset table`
Code: (copy&paste for gnuplot >=5.2)
### fill intersecting curves from two files not having identical x
reset session
$Data1 <<EOD
1 1
2 0
4 1
3 3
5 5
6 6
8 8
9 9
EOD
$Data2 <<EOD
1 3
3.5 5
7.5 1
9 7
EOD
# orientation of 3 points a,b,c: -1=clockwise, +1=counterclockwise
Orientation(a,b,c) = sgn((word(b,1)-word(a,1))*(word(c,2)-word(a,2)) - \
(word(c,1)-word(a,1))*(word(b,2)-word(a,2)))
# check for intersection of segment a-b with segment c-d,
# 0=no intersection, 1=intersection
IntersectionCheck(a,b,c,d) = \
Orientation(a,c,b) == Orientation(a,d,b) || \
Orientation(c,a,d) == Orientation(c,b,d) ? 0 : 1
# coordinate of intersection
M(a,b) = real(word(a,1)*word(b,2) - word(a,2)*word(b,1))
N(a,b,c,d) = (word(a,1)-word(b,1))*(word(c,2)-word(d,2)) - \
(word(a,2)-word(b,2))*(word(c,1)-word(d,1))
Px(a,b,c,d) = (M(a,b)*(word(c,1)-word(d,1)) - (word(a,1)-word(b,1))*M(c,d))/N(a,b,c,d)
Py(a,b,c,d) = (M(a,b)*(word(c,2)-word(d,2)) - (word(a,2)-word(b,2))*M(c,d))/N(a,b,c,d)
Intersection(a,b,c,d) = sprintf("%g %g", Px(a,b,c,d), Py(a,b,c,d))
stop = 0
do for [i=1:|$Data1|-1] {
a = $Data1[i]
b = $Data1[i+1]
do for [j=1:|$Data2|-1] {
c = $Data2[j]
d = $Data2[j+1]
if (IntersectionCheck(a,b,c,d)) {
i0 = i; j0 = j
stop=1; break }
}
if (stop) { break }
}
# create the datablocks for the outline to be filled
set print $Filled1
do for [k=1:i0] { print $Data1[k] }
print Intersection(a,b,c,d)
do for [k=j0:1:-1] { print $Data2[k] }
set print $Filled2
do for [k=|$Data1|:i0+1:-1] { print $Data1[k] }
print Intersection(a,b,c,d)
do for [k=j0+1:|$Data2|] { print $Data2[k] }
set print
set key top left
plot $Filled1 u 1:2 w filledcurves lc rgb 0x3f48cc, \
$Filled2 u 1:2 w filledcurves lc rgb 0xed1c24, \
$Data1 u 1:2 w lp pt 7 lw 5 lc rgb 0x99d9ea, \
$Data2 u 1:2 w lp pt 7 lw 5 lc rgb 0xff80c0
### end of code
Result:

GNUPLOT: Show a x value given a y value

i'm having some problems with gnuplot
I have to draw a cdf function and i'm interested in the values of variable x when F(x) is equal to 0.1 and 0.9
How can I tell Gnuplot to show me on the x axis the value corresponding to a given value on the y value (in my example those values are 0.1 and 0.9)
thanks
You're basically asking gnuplot to solve an equation. In your particular case, actually two equations: F(x)=0.1 and F(x)=0.9. As far as I know this cannot be done, but I might be wrong. What you can do if you simply want a graphical solution, is make a conditional plot, and ask that when F(x) is very close to 0.1 0.9, gnuplot plots something other than the function.
For example, assume f(x)=x^2 and you want to know "graphically" for which x f(x)=0.1. Then you can request the value abs(f(x) - 0.1) be small, for example < 0.01. Then tell gnuplot to go to zero (just an example!) if this is the case, otherwise plot f(x)=x^2:
f(x)=x**2
set xrange [-2:2]
set samples 1000
plot abs(f(x)-1) < 0.01 ? 0 : f(x)
Which yields:
The two peaks that go to zero mark graphically on the x axis the solution to the equation f(x)=0.1. Of course, you need gnuplot to sample this point in order to see a peak. Thus you need to play with set samples and set xrange.
From your question it is not clear whether you have a function F(x) as expression or just a x,y-data file. I assume that your function is monotonic increasing in x and y.
Two solutions come to my mind:
via simple linear interpolation
via curve fitting
Let's create some test data. For this, let's assume your function is known (as expression) and something like this (check help norm): F(x) = a*norm(b*x + c)
Let's take a = 1; b = 0.8; c = -4. In the example below, sampling will be only 8, just for illustration purpose.
You can easily set samples 200 and you will get the same results as for the curve fitting method below. From gnuplot 5.0 on, you could write the data into a datablock instead of a file on disk.
Data: SO22276755.dat
0 3.16712e-05
1.42857 0.002137
2.85714 0.043238
4.28571 0.283855
5.71429 0.716145
7.14286 0.956762
8.57143 0.997863
10 0.999968
Script 1: (basically works for gnuplot 4.6.0, March 2012)
### interpolate x-values
reset
FILE = "SO22276755.dat"
yis = '0.10 0.90'
yi(n) = real(word(yis,n))
xis = ''
xi(n) = real(word(xis,n))
Interpolate(yi) = (x1-x0)/(y1-y0)*(yi-y0) + x0
getXis(xis) = xis.(n=words(xis), n<words(yis) ? yi=real(word(yis,n+1)) : 0, \
y0<=yi && y1>=yi ? sprintf(" %g",Interpolate(yi)) : '')
set key left top noautotitle
set grid x,y
plot x1=y1=NaN FILE u (x0=x1,x1=$1):(y0=y1,y1=$2,xis=getXis(xis),y1) \
w l lc rgb "blue" ti "data", \
'+' u (xi=xi(int($0+1))):(yi=yi(int($0+1))):\
(sprintf("(%.4g|%.4g)",xi,yi)) every ::0::1 \
w labels point pt 7 lc rgb "red" right offset -1,0 ti "interpolated"
### end of script
Result:
Script 2: (basically works for gnuplot>=4.6.0, March 2012)
With this approach you are fitting your known function F(x) to constant lines, i.e. your desired values 0.1 and 0.9. For this, a file will be created (could be a datablock for gnuplot>=5.0) and it will basically look like this SO22276755.fit:
0 0.1
1 0.1
0 0.9
1 0.9
### interpolate x-values
reset
F(x) = a*norm(b*x+c) # function
a = 1
b = 0.8
c = -4
yis = '0.10 0.90'
yi(n) = real(word(yis,n))
xis = ''
xi(n) = real(word(xis,n))
set key left top noautotitle
set grid x,y
# create fit levels file
LEVELS = "SO22276755.fit"
set table LEVELS
set samples 2
plot for [i=1:words(yis)] '+' u (yi(i))
unset table
xmin = 0
xmax = 10
set xrange[xmin:xmax]
set samples 100
xis = ''
do for [i=1:words(yis)] {
xi = (xmin+xmax)*0.5 # set start value
fit F(xi) LEVELS u 1:2 index i-1 via xi
xis = xis.sprintf(" %g",xi)
}
plot F(x) w l lc rgb "web-green" ti "F(x)", \
'+' u (xi=xi(int($0+1))):(yi=yi(int($0+1))):(sprintf("(%.4g|%.4g)",xi,yi)) \
every ::0::1 w labels point pt 7 lc rgb "red" righ offset -1,0 ti "fitted"
### end of script
Result:

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.
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.
There are similar but slightly different questions:
GNUPLOT Plotting 5 day financial week
I have non-contiguous date/time X data and want non-contiguous X scale
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:
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)

Resources