I have a script I wrote that selects a block from a data file based on a command line argument. Up until now it has worked just fine. Now the graphs I'm getting out for the first 26 blocks have two sets of data in them. The data file should have about 190 blocks of data. I've thought and probed for an hour and I still have no idea why this might be happening. Here is the gnuplot script.
gnuplot << EOF
reset
set terminal png small size 1280,480
set output "graph_$1.png"
set yrange [-0.5:5.5]
set autoscale x
set lmargin 17
set label "SPILL" at -1,.5 right
set label "ON" at -1,1 right
set label "OFF" at -1,0 right
set label "DATA" at -1,2.5 right
set label "CLOCK" at -1,4.5 right
set xtics in scale .1 4 format ""
set grid
unset ytics
set key at -1,3.75 right
plot 'plotting' using 0:1 every :::$1::$1 title 'Results' with lines lt 1 lw 2, \
'' using 0:2 every :::$1::$1 notitle with lines lt 1 lw 2, \
'' using 0:3 every :::$1::$1 title 'Expected' with lines lt 3 lw 3, \
'' using 0:4 every :::$1::$1 notitle with lines lt 3 lw 3, \
'' using 0:5 every :::$1::$1 notitle with lines lt -1 lw 3
EOF
So when I make $1 to be anything from 0 to 26 it gives me multiple plots on one graph. If it's anything from 27 to 99 I know I get only one plot with only the data I want. I can't even find out where the second set of data on those first plots comes from. Sifting through the text in my data file to match it up would be extraordinarily tedious. Any help or advice on how to fix this double graphing would be greatly appreciated. Thank you.
Related
The recent release of gnuplot 5.4 came out with a lot of neat new features, to include the use of "spiderplots" (sometimes also called radar plots, etc.). Following their demos, I've been able to successfully plot a spiderplot using local data defined in the script. However, I can't seem to figure out how to do it using a data file (e.g. *.csv). I'd really like to do one similar to the last one on the demo list (multiple data series, markers, shading, etc.), but can't figure out the syntax on how to use the data from the file.
For something to work with, I've copied the array data from that last example script and converted it into a *.csv format. Feel free to use that as an example input file. Thank you for any/all help!
Array1,Array2
15,25
75,25
20,50
43,50
90,75
50,50
If you have the data file 'test.csv', the following script can be used to reproduce the last plot in demo.
set size ratio 1 1,1
# set title "To plot from 2 different files or arrays, use 'newspiderplot'"
set datafile separator comma
set spiderplot
set style spiderplot fs transparent solid 0.2 border lw 1 pt 6 ps 2
set for [i=1:6] paxis i range [0:100]
set paxis 1 tics font ',9'
set for [i=2:6] paxis i tics format ""
set grid spider lt black lc "grey" lw 0.5 back
set style data spiderplot
plot \
keyentry with spiderplot lc 3 lw 3 title "Array #1", \
for [i=1:6] "test.csv" every ::i::i using 1 lc 3 lw 3 title sprintf("Scale %d",i), \
newspiderplot, \
keyentry with spiderplot lc 4 lw 2 title "Array #2", \
for [j=1:6] "test.csv" every ::j::j using 2 lc 4 lw 2 notitle
You have 2 series of 6 axis data. The loop body of the following code picks one value of row-number i and column-number 1 from "test.csv", which is same value in original code using 'Array1[i]'.
This code
for [i=1:6] "test.csv" every ::i::i using 1 lc 3 lw 3 title sprintf("Scale %d",i), \
Original code
for [i=1:|Array1|] Array1 using (Array1[i]) lc 3 lw 3 title sprintf("Scale %d",i), \
FYI, |Array1| is the expression which means the number of elements in Array1.
I am trying make a line chart using Gnuplot. I need to get something like the following but with an exception:
In the example above you can see a straight line which joins two separate points over empty data. It is the one that crosses the '2016-09-27 00:00:00' x tick. I would like there would be a empty space instead of that straight line. How could I achieve this?
This is the current code:
set xdata time
set terminal pngcairo enhanced font "arial,10" fontscale 1.0 size 900, 350
set output filename
set key off
set timefmt '"%Y-%m-%d %H:%M:%S"'
set format x "%Y-%m-%d %H:%M"
set xtics rotate by -80
set mxtics 10
set datafile missing "-"
set style line 1 lt 2 lc rgb 'blue' lw 1
set style line 2 lt 2 lc rgb 'green' lw 1
set style line 3 lt 2 lc rgb 'red' lw 1
plot\
fuente using 1:2 ls 1 with lines,\
fuente using 1:3 ls 2 with lines,\
fuente using 1:4 ls 3 with lines
Three options:
In the data file, put an empty line where the gap is. This results in exactly what you want, but would also affect the other data from that file.
Use every to only plot a portion of the data and plot it twice, once up to the gap, once from the gap. Suppose that the gap occurs between data points 42 and 43 in your case, then you could use:
plot\
fuente using 1:2 ls 1 every ::::41 with lines,\
fuente using 1:2 ls 1 every ::42 with lines,\
fuente using 1:3 ls 2 with lines,\
fuente using 1:4 ls 3 with lines
(The every statement takes up to six arguments separated by colons but you can leave them empty for default values. The fifth argument is the end point, the third is the starting point.)
If you use - for missing data in your file (as indicated by your set datafile missing "-"), you have modify your using statement for this to be effective:
plot\
fuente using 1:($2) ls 1 with lines,\
fuente using 1:3 ls 2 with lines,\
fuente using 1:4 ls 3 with lines
Of course, you can always change your data and e.g. insert empty lines (as #Wrzlprmft suggested) when data is missing which will interrupt your line.
With large datasets and a lot of "breaks" this would be painful if you have to do it manually.
I would say that there is a solution without changing your data.
Let me ask: "What do you consider as missing data?"
My assumption would be: you have e.g. a data logger which takes values every 10 minutes.
If for some reason the logger did not take some data there will be a "gap" of missing data.
Now, you can define what you consider as a gap, e.g. >1 hour of no data would be a gap.
Hence, you simply compare two consecutive values t0 and t1 and if the difference is larger then your gap you change the line color from whatever color to transparent (according to the scheme 0xaarrggbb). Check help linecolor variable and help colorspec.
Script:
### don't show line in missing data gaps
reset session
myFmt = "%Y-%m-%d %H:%M"
# create some random test data
set print $Data
tStart = "2016-09-27"
tEnd = "2016-10-10"
t0 = strptime(myFmt,tStart)
t1 = strptime(myFmt,tEnd)
y0 = 100
do for [t=t0:t0+(t1-t0)*0.2:600] { print sprintf("%s %g",strftime(myFmt,t),y0=y0+(rand(0)-0.5)) }
do for [t=t0+(t1-t0)*0.3:t0+(t1-t0)*0.5:600] { print sprintf("%s %g",strftime(myFmt,t),y0=y0+(rand(0)-0.5)) }
do for [t=t0+(t1-t0)*0.8:t0+(t1-t0):600] { print sprintf("%s %g",strftime(myFmt,t),y0=y0+(rand(0)-0.5)) }
set print
set format x "%d.%m." timedate
gap = 3600 # 1 hour
myColor(tCol,color) = (t0=t1, t1=timecolumn(tCol,myFmt), t1-t0>gap ? 0xff123456 : color)
set multiplot layout 2,1
plot $Data u (timecolumn(1,myFmt)):3 w l lc rgb 0xff0000 ti "data as is"
plot t1=NaN $Data u (timecolumn(1,myFmt)):3:(myColor(1,0x0000ff)) w l lc rgb var ti "with removed gaps"
unset multiplot
### end of script
Result:
I am using gnuplot to postprocess some calculation that I have done and I am having hard time getting gnuplot to select the right lines as it is outputting some strange values that I do not know where come from.
The first 200 points of the results start in line 3 and stop in 202 but that is not working when I use every ::3::202.
Does anyone have any suggestions of what I am doing wrong?
Gnuplot image:
Datafile
set terminal pngcairo transparent nocrop enhanced size 3200,2400 font "arial,40"
set output "Mast41_voltage_muffe.png"
set key right
set samples 500, 500
set xzeroaxis ls 1 lt 8 lw 3
set style line 12 lc rgb '#808080' lt 0 lw 1
set style line 13 lt 0 lw 3
set grid back ls 12
set decimalsign '.'
set datafile separator whitespace
set ylabel "Spenna [pu]"
set xlabel "Timi [s]"
plot "mrunout_01.out" every ::3::202 using 2:3 title '5 ohm' with lines lw 3 linecolor rgb '#D0006E',\
"mrunout_01.out" every ::203::402 using 2:3 title '10 ohm' with lines lw 3 linecolor rgb '#015DD4',\
"mrunout_01.out" every ::403::602 using 2:3 title '15 ohm' with lines lw 3 linecolor rgb '#F80419',\
"mrunout_01.out" every ::603::802 using 2:3 title '20 ohm' with lines lw 3 linecolor rgb '#07826A'
unset output
unset zeroaxis
unset terminal
every refers to the actual plottable points. In your case, you have to skip 2 lines and the bunch of data at the end of your datafile.
Since you know the actual lines you need to plot I would pre-parse the file with some external tools like sed
So you can omit the every and your plot line becomes:
plot "< sed -n '3,202p' mrunout_01.out" using 2:3 title '5 ohm' with lp lw 3 linecolor rgb '#D0006E'
With yor datafile as it is, gnuplot has problems reading it. It can't even run stats on it:
stats 'mrunout_01.out'
bad data on line 1 of file mrunout_01.out
There is no need for using external tools, you can simply do it with gnuplot.
It's advantageous with your data that it is regular, every 200 points plotted in a different color.
And the data you want to plot is separated by one empty line from some additional data at the end of the file which you don't want to plot.
So, you simply address the 4th set of 200 lines in the 0th block via every ::600:0:799:0.
From help every:
Syntax:
plot 'file' every {<point_incr>}
{:{<block_incr>}
{:{<start_point>}
{:{<start_block>}
{:{<end_point>}
{:<end_block>}}}}}
Comments:
you can skip two lines at the beginning of the files with skip 2
you can plot your curves in a loop plot for [i=1:4] ...
you can define your color myColor(n) via index n from a string "#D0006E #015DD4 #F80419 #07826A"
you can define the legend myTitle(n) also from a list "5 10 15 20"
Script: (tested with gnuplot 5.0.0, version at the time of OP's question)
### plot parts of a file in a loop
reset session
FILE = "SO36103041.dat"
myColor(n) = word("#D0006E #015DD4 #F80419 #07826A",n)
myTitle(n) = word("5 10 15 20",n)
set xlabel "Timi [s]"
set ylabel "Spenna [pu]"
set yrange[0:30]
plot for [i=1:4] FILE u 2:3 skip 2 every ::((i-1)*200):0:(200*i-1):0 \
w l lw 3 lc rgb myColor(i) ti myTitle(i)
### end of script
Result:
My data file Im using for plotting:
0.005200 1
0.005333 2
0.005333 3
0.005333 4
0.005333 5
0.005467 6
0.005467 7
0.005467 8
My GNUplot script used for plotting:
#!/usr/bin/gnuplot
set xlabel "test"
set ylabel "value"
set grid ytics lt 0 lw 1 lc rgb "#bbbbbb"
set grid xtics lt 0 lw 1 lc rgb "#bbbbbb"
set autoscale
set terminal postscript portrait enhanced color dashed lw 1 'Helvetica' 14
set style line 2 lc rgb 'red' pt 7 # circle
set output 'test.eps'
plot 'data.txt' using 2:1 with points ls 2 title "time series plot"
Output image generated with GNUplot:
As you see in the data file I posted, value for the second, third, fourth and the fifth test is 0.005333. (As well as for the sixth, seventh and eighth test - there is a value of 0.005467).
But you can't see that on a figure - take a look at it. For the second, third, fourth and the fifth test the value on the figure is in somewhere between the 0.0053 and 0.00535 and I need the dots to be in the EXACT position on figure as its on the text file.
I have so much such files, is there any "portable" way to use it for every file I have?
The points are of course in the correct position. Add
set ytics add (0.005333, 0.005467)
to your script to see this:
After the answer got in my earlier post drawing vertical lines in between bezier curves, I have been trying to label the segments separated by the dotted lines. I used x2label but found out that if I use it multiple times then the data gets replaced though they are positioned in different places. Below is the script:
set term x11 persist
set title "Animation curves"
set xlabel "Time (secs.)"
set ylabel "Parameter"
set x2label "Phoneme1" offset -35
set pointsize 2
set key off
set style line 2 lt 0 lc 1 lw 2
plot [0.04:0.15] "curve.dat" u 1:2 smooth csplines ls 1, "" u 1:($2-0.2):(0):(0.3) w vectors nohead ls 2, \
"curve.dat" u 1:2 with points
The output is the following.
I want to label Phoneme1, Phoneme2...and so on.. on top of each segment. How would I do it? Also as I was suggested in my earlier post to play with the line "" u 1:($2-0.2):(0):(0.3) w vectors nohead ls 2 to get a top to bottom vertical lines. But that also did not work. How do I get the lines from top margin to bottom? Thank you.
The horizontal lines
The horizontal lines can be accomplished with setting the yrange to an explicit value. Otherwise gnuplot would try to get some space between the lines and the axis. You could choose the values
set yrange [0.3:1.2]
Then you simply modify the vector using directions like so:
"" u 1:(0.3):(0):(1.2) w vectors nohead ls 2
(see below for the complete script)
The labeling of the sections
A quick way of doing this with your set of data would be this:
set key off
set style line 2 lt 0 lc 1 lw 2
set yrange [0.3:1.2]
plot [0.04:0.15] "Data.csv" u 1:2 smooth csplines ls 1, \
"" u 1:(0.3):(0):(1.2) w vectors nohead ls 2, \
"" u ($1+0.005):(1):(sprintf("P %d", $0)) w labels
However, this will probably not look the way you want it to look. You could think of modifying your data file to also include some information about the labeling like:
#x-value y-value x-label y-label label
0.06 0.694821399177 0.65 0.1 Phoneme1
0.07 0.543022222222 0.75 0.1 Phoneme2
Then the labels line would simply look like:
"" u 3:4:5 w labels
The complete plot then looks like this: