According to figure above. this picture is generated from data points in text file. My question is that how can i remove the line at any two points if graph is jumped? (In my picture see that graph is jump about on x~260)
note that my purpose is that i just want to make this graph look like piecewise function that mean line on the middle of graph should not be connected because is jumped.
In gnuplot you can split a line in several parts either when you have an invalid data value somewhere, or an empty line.
For the first situation, you could check inside the using statement, if the difference to the previous point is too large, and invalidate the current point. But that would also make you loose not only the connecting line, but also the first point after the jump:
lim=3
y2=y1=0
plot 'test.dat' using (y2=y1,y1=$2,$1):($0 > 0 && abs(y2-y1) > lim ? 1/0 : y1) with linespoints
The test data file I used is
1 1
2 1.1
3 0.95
4 1
5 5
6 6
7 5.5
8 5.8
9 -2
10 -2.5
11 -4
As you see, the points at x=5 and x=9 are lost.
Alternatively, you can pipe your data through an external tool like awk for the filtering. In this case you can insert an empty line when the difference between two consecutive y-values exceeds some limit:
filter(lim) = 'awk ''{if(NR > 1 && sqrt((y-$2)**2) > '.lim.') print ""; print; y=$2}'' test.dat'
plot '< '.filter(3) using 1:2 with lines
Note, that I used the sqrt((..)**2) only to simulate an abs function, which awk doesn't have.
Related
I have a file called plot.txt with a number of values such as:
1 7.5000000000000000
2 10.312500000000000
3 11.660156250000000
4 12.425537109375000
5 12.913055419921875
6 13.248996734619141
7 13.493841290473938
8 13.679883163422346
9 13.825851876754314
10 13.943356417876203
This list continuous until about 450. When i try to plot it with lines i get a linear line across the graph. Why is this? line graph And how do I get rid of it?
open(newunit=write_unit,access='sequential',file='plotgnu.txt',status='unknown')
write(write_unit,*)'plot ''plot.txt'' with linespoints '
close(write_unit,status='keep')
!Kaller på gnuplot
call execute_command_line("gnuplot -persist plotgnu.txt")
When i plot it without linespoints I get the the correct graph just with points point graph
write(write_unit,*)'plot ''plot.txt'' '
Your data file contains the same data set four times without empty lines:
1 7.5000000000000000
2 10.312500000000000
...
437 14.999999999999998
438 14.999999999999998
1 7.5000000000000000
2 10.312500000000000
...
If you plot that with lines you do of course also get a line from the last point of the first "data set" to the first point of the second occurrence of the data set. And that is the line you are seeing.
I have a data file consisting of two blocks (separated by a single blank line) and would like to plot the difference between data from block 1 and block 2, i.e., something like
plot 'a.dat' using 1:($2_1-$2_2)
where $2_1 is supposed to mean "data from block 1, col.2" and $2_2 "data from block 2, col.2". Is that possible within Gnuplot, and if so, how?
Thanks,
Tom
This task is most likely not possible directly in Gnuplot, however, one can preprocess the data file first, using, e.g., gawk and then plot the modified file. For example:
dataFile="a.dat"
plotCmd(fname)=sprintf("<gawk '\
BEGIN{mode=0;l=0;} \
mode==0{if(NF==0){mode=1;}else{x[NR]=$1;y[NR]=$2;}} \
mode==1{if(NF>0){mode=2;l=NR;}} \
mode==2{print $1,y[NR-l+1],$2}' %s", fname)
plot plotCmd(dataFile) u 1:($2-$3) w l
The gawk script reads the file and saves the first and second column into arrays x and y until it reaches a blank line (zero number of fields). Then it skips all consecutive blank lines until it reaches a non-empty line (NF>0). It remembers the position of this line in the input file and then outputs for each line in the second block the x-coordinate together with the corresponding y-coordinate from the first block, i.e., a data file such as
1 2
2 4
3 6
1 4
2 8
3 12
would be transformed into
1 2 4
2 4 8
3 6 12
This assumes that the x-coordinates in both blocks match...
I have a file with a matrix like :
1 2 3
4 5 6
7 8 9
Using gnuplot, I would like to extract the Variable in the 3th row on the 2th column, and store it in a variable called X for example. please how to do that using gnuplot.
Thanks
You can do that within a plot command,
set table "/dev/null"
X=0
X_row=3
X_col=2
plot "file.dat" using (($0==X_row)?(X=column(X_col),X):0)
unset table
To save time the plot command can do something useful at the same time, like... plotting something.
Thanks, It's solved actually using this syntax :
plot u 0:($0==RowIndex?(VariableName=$ColumnIndex):$ColumnIndex)
#RowIndex starts with 0, ColumnIndex starts with 1
print VariableName
It's already explained quite well here :
by #StackJack
I have temporal data, where some time intervals contain only missing values. I want to show explicitely those missing values intervals.
For now, the solution I have is to check whether the value is NaN or not, as such:
plot file_name using 1:(stringcolumn(num_column) eq "NaN" ? 1/0 : column(num_column)) with lines,\
"" using 1:(stringcolumn(num_column) eq "NaN" ? 1000 : 1/0) with points
Which will result in drawing points at y = 1000 instead of the line for missing values, which gives the following result:
However, this is not ideal because a) I need to specify a y value at which to draw the points and b) it's quite ugly, especially when the dataset is longer in time.
I would like to produce something like this instead:
That is, to fill completely this interval with a color (possibly with some transparency unlike my image). Note that in these examples there is only one interval of missing values, bu in reality there can be any number of them on one plot.
We can do some pre-processing to accomplish this. Suppose that we have the following data file, data.txt
1 8
2 6
4 NaN
5 NaN
6 NaN
7 9
8 10
9 NaN
10 NaN
11 6
12 11
and the following python 3 program (obviously, using python is not the only way to do this), process.py1
data = [x.strip().split() for x in open("data.txt","r")]
i = 0
while i<len(data):
if (data[i][1]=="NaN"):
print(data[i-1][0],end=" ") # or use data[i][0]
i+=1
while data[i][1]=="NaN": i+=1
print(data[i][0],end=" ") # or use data[i-1][0]
else: i+=1
This python program will read the data file, and for each range of NaN values, it will output the last good and next good x-coordinates. In the case of the example data file, it outputs 2 7 8 11 which can be used as bounds for drawing rectangles. Now we can do, in gnuplot2
breaks = system("process.py")
set for [i=0:words(breaks)/2-1] object (i+1) rectangle from word(breaks,2*i+1),graph 0 to word(breaks,2*i+2),graph 1 fillstyle solid noborder fc rgb "orange"
Which will draw filled rectangles over this range. It determines how many "blocks" (groups of two values) are in the breaks variable then reads these two at a time using the breaks as left and right bounds for rectangles.
Finally, plotting the data
plot "data.txt" u 1:2 with lines
produces
which shows the filled rectangles over the range of NaN values.
Just to provide a little more applicability, the following awk program, process.awk3 serves the same purpose as the above python program, if awk is available and python isn't:
BEGIN {
started = 0;
last = "";
vals = "";
}
($2=="NaN") {
if (started==0) {
vals = vals " " last;
started = 1;
}
}
($2!="NaN") {
last = $1
if (started==1) {
vals = vals " " last;
started = 0;
}
}
END {
sub(/^ /,"",vals);
print vals;
}
We can use this by replacing the system call above with
breaks = system("awk -f process.awk data.txt")
1 The boundaries are extended to the last and next point to completely fill the gap. If this is not desired, the commented values will cover only the region identified by NaN in the file (4-6 and 8-10 in the example case). The program will not handle NaN values as the first or last data point.
2 I used solid orange for the gaps. Feel free to use any color spec there.
3 The awk program extends the boundaries in the same way as the python program, but takes more modification to get the other behavior. It has the same limitations in not handling NaN values as the first or last data point.
Using two filled curves
A somewhat "hacky" way of doing it is using two filled curves, as such:
plot file_name using 1:(stringcolumn(num_column) eq "NaN" ? 1/0 : column(num_column)) with lines ls 2,\
"" using 1:(stringcolumn(num_column) eq "NaN" ? 0 : 1/0) with filledcurve x1 ls 3,\
"" using 1:(stringcolumn(num_column) eq "NaN" ? 0 : 1/0) with filledcurve x2 ls 3
Both filledcurve must have the same linestyle, so that we get one uniform rectangle.
One filledcurve has x1 as parameter and the other x2, so that one fills above 0 and the other below 0.
You can remove the curve at 0 and make the filling transparent using this:
set style fill transparent solid 0.8 noborder
This is the result:
Note that the dashed line at 0 under the rectangle is a bit glitchy compared to the other dashed lines. Note also that if some rectangles are very small in width, they will look lighter than expected.
I have some values given by clock time, where the first column is the time. However, the values until 2 o clock still belong to the current day. Given
3 1
12 4
18 1
21 2
1 3
2 0
named as test.data, I'd like to print this in gnuplot:
set xrange [0:24]
plot 'test.data' with lines
However, the plot contains a backward line. It's striking through the whole diagram.
Is there a way to tell gnuplot to explicitly not print such backward lines, or even better, print them wrapping around the x axis (e.g. in my example drawing the line as a forward line up to 24, and then continuing it at 0)?
Note: The x axis of the plot should still start at 0 and end at 24.
As far as wrapping over the edge of the graph (a pac-man like effect), gnuplot can't do that on it's own. Even doing it manually, you would have to somehow calculate the right point to re-enter the graph based on the slope of the connecting line, and insert a new point into the data to control where the re-entry line enters, and where the exiting line exits. This would require external processing.
If you can do some outside preprocessing, adding a blank line before the 1 3 line will insert a discontinuity into the plot and prevent gnuplot from connecting those points (see help datafile for how gnuplot handles blank lines). Of course, you could always sort the data too.
I would recommend sorting the data before plotting, but if you do want to do this wrapping effect, the following python program (wrapper.py) will set up the data for it
data = [tuple(map(float,x.strip().split(" "))) for x in open("data.txt","r")]
data2 = sorted(data)
back_in_to = data2[0]
out_from = data2[-1]
xdelta = back_in_to[0] + 24 - out_from[0]
ydelta = back_in_to[1] - out_from[1]
slope = ydelta/xdelta
outy = out_from[1] + (24-out_from[0])*slope
print(0,outy)
for x in data2:
print(*x)
if x[0]==data[-1][0]: print("")
print(24,outy)
It reads in the data (assumed to be in data.txt, and calculates the points where a line should leave the graph and where it should re-enter, adding these points to the sorted data. It adds a blank line after the last point in the original graph, causing the break in the line. We can then plot like
plot "< wrapper.py" with lines
If we look at your original plot
we see the backward line that you referred to which reaches from the furthest right point to the next left point. The plot that the python program pre-processed reaches through the right of the graph to move back to this point.