Plot vertical lines in Gnuplot to represent one dimensional data - gnuplot

I am trying to plot the bandwidth growth of a TCP connection using Gnuplot.
I have 2 log files, one with bandwidth at a time, and another with time stamps at which a packet drop occurs. I want to represent the packet drops in the same graph as the bandwidth, possibly with a vertical line on the X axis (time).
Please provide suggestions!
Just as a very rough example, here are the file formats.
Bandwidth.dat
0.001 2
0.002 3
0.003 5
0.004 8
Packet_Drop.dat
0.006
0.12
0.39
Required plot:
Sorry, didn't know how to make a better graph quickly!

As one option you could use the impulses plotting style, which plots vertical lines from y=0 to the given value:
max = 10
plot 'Bandwidth.dat' using 1:2 with lines linecolor rgb 'black',\
'Packet_Drop.dat' using 1:(max) with impulses linecolor rgb 'red'
The backdraw with this option is, that you must know the maximum value of the y-axis. You can get this e.g. by plotting to the unknown terminal, and then use the GPVAL_Y_MAX value:
set terminal push # save current terminal
set terminal unknown
plot 'Bandwidth.dat' using 2
set terminal pop # restore terminal
plot 'Bandwidth.dat' using 1:2 with lines linecolor rgb 'black',\
'Packet_Drop.dat' using 1:(GPVAL_Y_MAX) with impulses linecolor rgb 'red'
(One cannot use stats to get the maximum value of an autoscaled axis.)
Alteratively you can read in the x-values from your data file into a string and iterate over the words and set some arrows accordingly. On Linux, use
packet_drop = system('cat Packet_Drop.dat')
set for [w in packet_drop] arrow from first w, graph 0 to first w, graph 1 linecolor rgb 'red' nohead
plot 'Bandwidth.dat' using 1:2 with lines lc rgb 'black'
On Windows it should work with
packet_drop = system('type Packet_Drop.dat')
and you need to use the wgnuplot_pipes.exe when using version 4.6.

Related

Gnuplot XRD graph, connecting points

I have a XRD data and when I plot it I want to have this kind of graph. Anyway, excel has a problem to plot too large data and I want to plot it with Gnuplot and here is my code
set title "GNUPLOT RESULT"
set xlabel "Wavelength 2Theta"
set ylabel "Intensity"
set xrange [20:90]
set key right center
set terminal pngcairo size 1600, 1000 enhanced font "Arial,16"
set output "Allt-XRD.png"
plot "AllW" using 1:2 w p pt 7 ps 2 lc rgb "orange" title "point", "AllW" using 1:2 smooth acspline lw 3 lc rgb 'blue' title 'spline'
But what it produces, it does not connect all dots/points and I do not know but somehow it has a preferences (is it a weight point?) to connecting them.
Question
How can I connect all the dots as seen at excel graph with Gnuplot
Thanks in advance
P.S: I tried all bunch of smooth version acscpline' cspline' bezier etc. it did not work
Edit 1: The line plot who wonders why I do not try it
Edit 2: The worked answer of user8153 : Use decimal data point not an integer. Both spline and points option plot perfectly the data as it seen below
How XRD data looks like, it is too long so I pasted only a few of them
Wavelength = 1.54059 Å (Cu)
Angle Intensity
20.00243 1467
20.02869 1533
20.05495 1482
20.08121 1468
20.10747 1376
20.13374 1421
20.16000 1433
20.18626 1380
20.21252 1431
20.23878 1405
20.26504 1357
20.29130 1374
20.31756 1413
Your with points plot shows that your data contains only integer values of the wavelength, but each value has multiple intensities associated with it. Is that really what the data should look like, or was there some mistake that chopped off the values of the wavelengths after the decimal point? Maybe your data file uses a symbol for the decimal point that gnuplot doesn't recognize? If so, use set decimalsign so gnuplot realizes that you are feeding it floating point numbers.
As it is, gnuplot does precisely what you tell it to do: it plots all these points at the same x coordinate, and connects them with lines if you use with lines, which are then by construction vertical.
You told it to plot "with points pointtype 7 pointsize 2" (shorthand "w p pt 7 ps 2"). So it did.
If you want it to plot with lines then say "with lines".
plot "AllW" using 1:2 with lines lc rgb "orange" title "lines"

Use linetype and color to distinguish many plots on the same graph in gnuplot 5

I am plotting something like 40 plots on the same figure in gnuplot 5. The standard palette quickly runs out of colors, so that it's impossible to distinguish which plot is which. An example (with 10 plots instead of 40, for clarity) is below
If I could tell gnuplot to change dashtype as it runs out of colors, I would easily be able to tell the plots apart. How can I do that?
Nota Bene: the linetype behaviour changed in gnuplot 5. Commands that work in gnuplot 4 will probably fail in gnuplot 5.
A possible solution is to change the dashtype every eight plots. In a plot for command, this can be done like this:
plot for [i = 70:80] 'run'.i.'/e2e.txt' every 1 u 1:2 w l t ''.i dashtype i/8
this works, but the dashtype used are the 7 and 8 ones, which are quite similar to each other and hard to tell apart. Also this is a manual way of fixing it, and therefore error-prone and has to be re-engineered every time I plot something different. Ideally, I would like to change the default linestyle so that the change is performed automatically.
I'm posting the answer here to share a possible solution, in case someone needs it before a better one is provided.
In gnuplot you have color, linewidth (lw), dashtype (dt), pointtype (pt), pointsize (ps) as differentiators.
In your noisy and crowded plot, I would say pt, ps and lw are pretty much out of question.
Distinguishing 40 colors in a graph would be a challenge even for non-color-blind people.
My guess is that you want a quick overview about these curves to "quickly" check how the curves behave (like finding some outliers or different shape or max or min values).
As you said: color and dashtype remain.
In your answer you went for the standard 8 gnuplot colors and 5 dashtypes. You already noticed that some dashtypes are hard to differentiate, depending on the linewidth and graph size.
Well, if you are using an ineractive terminal then you could always zoom in and differentiate the dashtypes (or maybe even pointtypes).
The example below uses 20 colors and 2 dashtypes via a defined palette. Two neigbouring curves have a different dashtype to have a clear differentiatior. The code can easily be changed, e.g. to 10 colors and 4 dashtypes.
Script:
### attempt to display 40 different distinguishable curves
reset session
N=40
# create some random test data
set print $Data
do for [b=1:N] {
y0 = rand(0)*300+100
do for [r=1:200] {
print sprintf("%d %.1f",r,y0=y0+rand(0)*10-5)
}
print ""
print ""
}
set print
set palette defined (0 "red", 1 "green", 2 "blue", 3 "magenta", 4 "yellow", 5 "cyan", 6 "black") maxcolors 20
set key out
set cbrange [0:40]
set cbtics 0,4,40
set mcbtics 4
# unset colorbox # uncomment this line if you want to remove colorbox
plot for [i=1:N] $Data u 1:2:(column(-2)) index i-1 w l lc palette lw 1.4 dt dt=((i+1)%2)*2+1 ti sprintf("%d",i)
### end of script
Result:

gnuplot: multiplots using multiple lines in each plot and in-line data

I am trying to call gnuplot from torch in order to plot several things. I am trying to use multiplots (like subplots in matlab), and at the same time plot different curves in the same plots. Furthermore, I'm defining the data in-line, i.e., avoiding writing the data in external files (plot '-').
I've tried plotting several curves with '-' in several ways, with multiplot previous and next, with replot... but any combination messes up the layout in one way or another. Does anybody knows how to do this or can give some hints?
Thanks!
Update: Added a small example. Blue and red lines should be plotted in the same plot (top one), while green one should be plotted alone in the bottom one.
Example:
gnuplot.figure(1)
gnuplot.raw('set terminal x11 0 position 1200,20 persist')
gnuplot.raw('set multiplot layout 2,1')
gnuplot.raw([[plot '-' lt rgb 'blue'
0 0
100 30
e]])
gnuplot.raw([[plot '-' lt rgb 'red'
0 30
100 60
e]])
gnuplot.raw([[plot '-' lt rgb 'green'
0 60
100 90
e]])
gnuplot.raw('unset multiplot')
I'm not familiar with torch, but I think your problem is with trying to do three separate plot statements. In gnuplot, to do multiple curves in the same plot (two in your top plot), you specify them in the same command separated by a comma. Feeding inline data, this means that you will need to provide one set of data, end it with e, provide another, and then end it with e.
Additionally, you can use lc (linecolor) instead of lt to set your colors.
In straight gnuplot, you will do this like so:
set terminal x11 0 position 1200,20 persist
set multiplot layout 2,1
plot '-' lc rgb 'blue', '-' lc rgb 'red'
0 0
100 30
e
0 30
100 60
e
plot '-' lc rgb 'green'
0 60
100 90
e
unset multiplot
If you want lines, just add with lines to all three plot specifications like
plot '-' lc rgb 'blue' with lines, '-' lc rgb 'red' with lines
plot '-' lc rgb 'green' with lines
or change the default data style with set style data lines.

Gnuplot: draw error bars of data points outside plotting range

If I set a specific yrange and plot in a pdf terminal with this plot command:
plot "data.dat" u 1:4:5:6 w yerrorbars pt 6 ps 0.5 t "R_t"
errorbars that belong to data points outside the yrange, but end inside the yrange are not shown.
How do I force gnuplot to draw those. I already tried "set clip one/two"
The only workaround I found is to plot the data 3 times, once for the central point and once for each side of the error bar.
Use "-" as symbol for the errorbars and use their own "errorbars" to draw a line to the central point.
You could use multiplot to achieve this.
Set your plot to have zero margins, so the axes are on the border of the canvas, and switch of all tics and borders for the first plot.
Switch on the axes, tics etc. again, and do an empty plot that you set at the correct position using set size and set origin. You'll have to do some math to calculate the exact position.
#MaVo159, you can reduce it to plotting only twice by using with yerrorbars and with vectors (check help vectors). You need to set the proper arrow style, check help arrowstyle.
However, this works only for gnuplot>=5.2.3, for earlier versions there seems to be a bug which plots the arrowhead at the wrong side for some of the vectors extending the graph.
You nevertheless have to plot once with yerrorbars in order to get the proper legend.
Script: (works for gnuplot>=5.2.3, May 2018)
### plot errorbars from points outside the range
reset
$Data <<EOD
1 9 5.11 8.32
2 8 6.20 9.22
3 6 5.31 6.31
4 5 4.41 5.51
5 4 3.31 4.71
6 2.9 2.81 3.71
7 2 1.11 3.41
EOD
set yrange[3:7]
set offsets 1,1,0,0
set style arrow 1 heads size 0.05,90 lw 2 lc 1
set multiplot layout 2,1
plot $Data u 1:2:3:4 w yerrorbars pt 6 ps 2 lw 2
plot $Data u 1:2:3:4 w yerrorbars pt 6 ps 2 lw 2, \
'' u 1:3:(0):($4-$3) w vec as 1 notitle
unset multiplot
### end of script
Result:
You could modify your data file: Because the central value of the data point is outside the plot range you could set it equal to the errorbar's end point that would be still visible in your plot.
Example:
plot range: set yrange[-2:2]
data point: 1, -3, -1, -4 (x, y, ylow, yhigh)
set data point to: 1, -1, -1, -4
Attention: Since you have to edit your data file you should
Make a copy of the original data file
Be very careful when editing the file
Keep in mind, that when changing the plot range such that the central
value of the data point becomes visible you have to use the original data point. Otherwise you will see the correct error bar but there will be no central value plotted. (this is equivalent to setting 'point type' to 0)

Displaying markers on specific values in Gnuplot's line plot

I have data for a CDF in a file which looks like the following:
0.033 0.0010718113612
0.034 0.0016077170418
0.038 0.0021436227224
... ...
... ...
0.847 0.999464094319
0.862 1.0
First column is the X-axis value and the second column is the CDF value on Y-axis. I set the line style as follows:
set style line 1 lc rgb 'blue' lt 1 lw 2 pt 7 ps 0.75 # --- blue
and subsequently plot the line with the following:
plot file1 using 1:2 title 'Test Line CDF' with linespoints ls 1
This all works fine, the problem seems to be that my CDF file is pretty big (about 250 rows) and Gnuplot would plot the marker/point (a circle in this case) for every data point. This results in a very "dense" line because of the over-concentration of markers such that the underlying line is almost not visible as I show in an example image below:
How can I selectively draw the markers so that instead of having them on all data points, I plot them after every 50 data points, without having to decrease the number of data points (which I believe is what "every n" in the plot command would do) in my data file or decrease the marker size?
There is no need to use two plots commands, just use the pointinterval option:
plot 'data' pointinterval 5 with linespoints
That plots every line segment, but only every fifth point symbol.
The big advantage is, that you can control the behaviour with set style line:
set style line 1 lc rgb 'blue' lt 1 lw 2 pt 7 ps 0.75 pi 5
plot 'data' w lp ls 1
You can plot the same function twice, once with lines only, and then with points every n points. This will draw less points without decreasing the amount of segments. I think this is what you want to achieve. For this example I have done set table "data" ; plot sin(x) to generate numerical sampling of the sin(x) function.
What you have at the moment is:
plot "data" with linespoints pt 7
which gives
Now you can do the following:
plot "data" with lines, "data" every 10 with points pt 7 lc 1
which gives what you want:
You can change the styling to meet your needs.
Although #Miguel beat me to it, but I'm also posting my solution below:
The idea is to once draw the line and then draw the points with the "every n" specifier. I changed my own Gnuplot script in the following manner. A kind of hack but works:
set style line 1 lc rgb 'blue' lt 1 lw 2 pt 7 ps 0 # --- blue
plot file1 using 1:2 title '' with linespoints ls 1, "" using 1:2 every 20 title 'Test Line CDF' with points ls 1 ps 0.75
This retains the nice curve, without quantizing it too coarsely while also keeping the points much better spaced.

Resources