plot data at variable points using gnuplot - gnuplot

Here is my data file
seconds data
(x-axis ( y axis
points) points)
3.880000, 20
3.920000, 10
3.960000, 20
4.000000, 20
4.080000, 20
4.120000, 20
4.570000, 20
4.620000, 10
4.650000, 10
4.690000, 10
4.750000, 20
.
.
.
and so on
I want to plot points in column 2 at positions specified by column 1
ie I want 20 , 10 , 20 20, 20 etc to be present at 3.88 , 3.92, 3.96 on xaxis
Can anybody tell me how to do this ?

Suppose your data is in 1.txt:
plot "1.txt" using 1:2

I know it's been a long time, but for anyone else who stumbles upon this...
For this datafile, you'll also need a set datafile separator ','
e.g.
set datafile separator ','
plot 'data.dat' using 1:2
As a matter of style, it is probably best practice to explicitly comment out the header of the datafile using '#' characters. e.g.
# seconds data
# (x-axis ( y axis
# points) points)
3.880000, 20
3.920000, 10
3.960000, 20
4.000000, 20
4.080000, 20
4.120000, 20
4.570000, 20
4.620000, 10
4.650000, 10
4.690000, 10
4.750000, 20
For this simple example, it works without the comments, but other, more complicated datafiles may not.

Related

Redrawing Excel figures on gnuplot

I was working on excel and drew two histograms shown below, I have been told to redraw them using gnuplot on windows which is very new to me.
The original graph that I want to redraw is this.
Area 1 Area 2
Case 1 Case 2 Case 1 Case 2
Parameter 1 36 66 31 72
Parameter 2 57 91 44 85
Parameter 3 62 90 50 85
My file is a text file and I wrote the above table as follows as I am not sure how to group the different columns together.
Area Area1 Area1 Area2 Area2
Case Case1 Case2 Case1 Case2
Parameter_1 36 66 31 72
Parameter_2 57 91 44 85
Parameter_3 62 90 50 85
I used the following commands and got a histogram that is grouped in the wrong way.
clear
reset
unset key
set style data histogram
set style fill solid border
set style histogram clustered
plot for [COL=2:5] 'date_mins.tsv' using COL:xticlabels(1) title columnheader
Kindly guide me on how to group columns together and also how to add the numbers on top of the bars. {The graph should be same as the one excel generated one.}
To be honest I'm regularly puzzled with histograms in gnuplot, apparently I'm not the only one. In gnuplot console, check help histograms.
Although, there are a few histogram examples on the gnuplot homepage, but of course not all possible variations can be covered.
Apparently, this plotting style is a bit confusing to understand.
This would maybe explain that there are more than 800 questions on SO on histograms with gnuplot.
I'm not sure if or how you can get your desired histogram efficiently, maybe there is an easy way.
I would do it "manually" with the plotting style with boxes.
Check the example below as a starting point. There are a few strange workarounds included, e.g. getting the titles into an array in an earlier plot for later use.
Code:
### special histogram
reset session
$Data <<EOD
Area Area1 Area1 Area2 Area2
Case Case1 Case2 Case1 Case2
"Parameter 1" 36 66 31 72
"Parameter 2" 57 91 44 85
"Parameter 3" 62 90 50 85
EOD
set style fill solid noborder
set boxwidth 0.8
set key noautotitle out center bottom horizontal reverse Left samplen 1 width 2
A=2 # Areas
C=2 # Cases
P=3 # Parameters
g=1 # gap
PosX(a,c,p) = ((a-1)*C*(P+g)) + (c-1)*(P+g) + p
PosY(a,c) = column((a-1)*C+c+1)
PosXArea(a) = (PosX(a,C,P)+PosX(a-1,C,P))*0.5
PosXCase(a,c) = (PosX(a,c,P)+PosX(a,c-1,P))*0.5
myColor(p) = int(word("0x5b9bd5 0xed7d31 0xa5a5a5",int(p)))
myValue(a,c) = strcol((a-1)*C+c+1)
set grid y
set xlabel "\n\n\n" # get empty space below the plot
set format x "" # no xtic labels
set yrange[0:]
array Titles[P] # array for titles
plot for [a=1:A] for [c=1:C] $Data u (PosX(a,c,$0)):(PosY(a,c)):(myColor($0+1)) skip 2 w boxes lc rgb var , \
for [a=1:A] for [c=1:C] '' u (PosX(a,c,$0)):(PosY(a,c)):(Titles[int($0+1)]=strcol(1), myValue(a,c)) skip 2 w labels offset 0,0.7, \
for [a=1:A] for [c=1:C] '' u (PosXCase(a,c)):(0):(myValue(a,c)) every ::1::1 w labels offset 0,-1, \
for [a=1:A] '' u (PosXArea(a)):(0):('\n\n'.myValue(a,1)) every ::0::0 w labels offset 0,-1, \
for [p=1:P] keyentry w boxes lc rgb myColor(p) ti Titles[p]
### end of code
Result:

gnuplot: change x-axis to start from specific numer

I have a file named 'data.txt':
25
76
90
100
120
135
And I want to make my plot x-axis looks like this:
0 4 8 12 16 20 24
I want to put first value from file to the plot on 4 position then next value to 8 position and so on. How can I do that?
similar questions have been asked here already, however, I can't recall what the titles were...
In gnuplot, check help pseudocolumns. $0 gives you the line number of the datafile, starting from 0. So, just multiply this with 4 and you'll have your added x-values.
plot "data.txt" u ($0*4):1 w lp pt 7 lc rgb "red"
Result:

plot 10 line sof 1000 values on gnuplot

I have a data file with 10 lines with 1000 values each line and I'm trying to plot this values with this script
#!/usr/bin/gnuplot -persist
plot "data.dat" using [1:1000] title "" with lines
but I get this error
plot "data.dat" using [1:1000] title "" with lines
^
"./plot.sh", line 3: invalid expression
How can I indiate a interval form the first value to the 1000 value?I't posible to set a diferent random clor to every line?
As #vaettchen pointed out, gnuplot wants data in columns and plotting rows is not straightforward. So, best would be if your data was transposed. Unfortunately, gnuplot has no function to transpose data. So, you have to use external tools to transpose your data.
Although, if your data is 10 lines with 1000 values each, i.e. a strict 10x1000 matrix, you could do something with gnuplot only (see below).
However, if your data is not a strict matrix, e.g. one line has more or less values or one value missing the method below won't work.
The following example (just 5 lines with 7 values each) illustrates plotting columns and plotting rows.
### plotting columns and rows
reset session
set colorsequence classic
$Data <<EOD
11 12 13 14 15 16 17
21 22 23 24 25 26 27
31 32 33 34 35 36 37
41 42 43 44 45 46 47
51 52 53 54 55 56 57
EOD
# get the number of rows
stats $Data u 0 nooutput
RowCount = STATS_records
# do the plot
set multiplot layout 1,2
set title "Plotting columns"
set xlabel "Row no."
set xtics 1
# plot all columns from 1 to *(=autodetection)
plot for [i=1:*] $Data u ($0+1):i w lp pt 7 not
set title "Plotting rows"
set xlabel "Column no."
# plot all rows
plot for [i=0:RowCount-1] $Data matrix u ($1+1):0 every :::i::i w lp pt 7 not
unset multiplot
### end of code
Which results in:

Specific gnuplot by data grouping

I'm new in gnuplot and sorry that my problem formulation might be unprecise, but I don't know how to find the tools/commnds needed to solve my problem. The code for plotting I would like to integrate in my bash file.
I have a data set like:
285 1 50 7.35092
265 1 50 7.35092
259 1 50 7.35092
258 1 50 7.35092
264 1 50 7.35092
491 5 50 33.97
488 5 50 33.97
495 5 50 33.97
492 5 50 25.1649
495 5 50 33.0725
500 5 50 13.6176
507 5 50 32.2502
489 5 50 33.0725
494 5 50 33.97
491 5 50 33.97
746 10 50 34.6007
746 10 50 34.6007
767 10 50 30.858
745 10 50 34.8789
746 10 50 34.6007
747 10 50 34.6007
758 10 50 34.6007
772 10 50 34.60
I already grouped the data by entering a new line between blocks. I would like to calculate for each block the mean and standard deviation of the 4th column.
Then I would like to plot on the Y axes the mean with the confidence interval (standard deviation) and on the X axes the value from the second column.
Each data block has a unique number in the 2nd column.
Solution: so far I got the values for a point from the first block but while I try to plot I get an error:
#myBash code for plotting.sh
FILEIN=simulationR.txt
rm plotTestR.png
gnuplot << EOF
reset
set terminal png
set output 'plotTestR.png'
set ylabel 'reward'
set xlabel 'Nr of simualtion'
set title 'Simualtio duration'
set grid
stats "$FILEIN" using 4 every :::0::0 nooutput
mean1 = sprintf('%.3f', STATS_mean)
std1 = sprintf('%.3f', STATS_stddev)
stats "$FILEIN" using 2 every :::0::0 nooutput
x1 = sprintf('%.3f', STATS_max)
plot '-' w yerrorbars title std1
x1 mean1 std1
exit
EOF
and the error:
gnuplot> plot '-' w yerrorbars title std1
^
line 1: Bad data on line 1 of file -
Usually, gnuplot isn't made for such data processing tasks. That's best done with an external script, which does the processing and writes to stdout, which can then be feed directly to gnuplot like
plot '< python myscript.py simulationR.txt'
In your example, you can only have fixed data after the plot '-' part, no variable substitution is done here.
However, gnuplot version 5 introduces a new inline data structure, to which you can write your computed values (set print $data).
Note, that the following is a plain gnuplot script, if you want to wrap it in a bash script (which is not necessary, since you can pass variables to a gnuplot script via the command line), then you must escape the $ characters.
FILEIN="simulationR.txt"
system('rm -f plotTestR.png')
reset
set terminal pngcairo
set output 'plotTestR.png'
set ylabel 'reward'
set xlabel 'Nr of simulation'
set title 'Simulation duration'
set grid
set print $data
do for [i=0:2] {
stats FILEIN using 2:4 every :::i::i nooutput
print sprintf("%e %e %e", STATS_max_x, STATS_mean_y, STATS_stddev_y)
}
set autoscale xfix
set offsets 1,1,0,0
plot $data using 1:2:3 w yerrorbars
A further improvement could be to separate two blocks by two blank lines, in which case you can use
stats 'simulationR.txt' using 0 nooutput
to have the number of blocks in the variable STATS_blocks, and you can rewrite the loop as
do for [i=0:STATS_blocks-1] {
stats FILEIN using 2:4 index i nooutput
print sprintf("%e %e %e", STATS_max_x, STATS_mean_y, STATS_stddev_y)
}

How to mark 90 percentile in gnuplot

How to mark 90 percentile in gnu plot. sample needed
plot [][] "fle.txt" using 1:2 with lines
This is how i plot the graph i want to mark the 90% in the graph
this is my data set
time(seconds) frequency cumulativeFrequency
10 2 2
11 6 8
12 8 16
13 10 26
14 7 33
15 5 38
16 5 43
17 4 47
18 2 49
I can't see any way to do this in gnuplot by itself, but it's not hard to do using python --
# percent90.py
import sys
def to_num(iterable):
for line in iterable:
columns = line.split() # split into columns
if not columns: # empty line
continue
try:
yield float(columns[1]) # This is a good number -- Yield it and keep going
except ValueError: # Not a number on the line
pass # just keep going -- do nothing
except IndexError:
print line
with open(sys.argv[1]) as fin:
data = sorted(to_num(fin))
top_10 = data[int(len(data)*0.9):] #top 10 percent of the data
print(top_10[0])
which you can call something like:
python percent90.py path/to/datafile
This will tell you where to place your mark. As for marking it, I would probably do something like this in gnuplot:
YVAL = `python percent90.py path/to/datafile`
set arrow 1 from graph 0,first YVAL to graph 1,first YVAL ls 1 nohead front
If you just want to compute the 90% point of the data, this could be done with the stats or plot command and gnuplot's internal variables, then draw a line as mgilson suggested:
#!/usr/bin/env gnuplot
set terminal png
set output 'test.png'
# 'every ::1' skips header
stats 'fle.txt' every ::1
mark = (STATS_max_y - STATS_min_y)*0.9 + STATS_min_y
set arrow 1 from graph 0,first mark to graph 1,first mark ls 1 nohead front
plot 'fle.txt' every ::1
This script produces this output:

Resources