How to plot a specific graph in gnuplot - plot

I have a file that I need to plot in a graph that looks similar to this:
gnuplot sample graph
Here is my file that I am trying to plot:
441.81 823.36 192765 3044.68 4242.61
X 2609.3 4901.96 8306.6 12058.18
1632.27 4098.15 9299.14 16295.19 24665.59
I can do a simple plot, but changing the line types and using a file is what I am having trouble with. I'm not sure how to get the data from the file into the plot and make it formatted like the sample image.

You probably should dig a little deeper into gnuplot. A good start is this article on plotting data.
Anyway, let's define three distinct line styles:
set style line 1 lc 'blue' lt 1 lw 2 pt 6 ps 1.5
set style line 2 lc 'red' lt 1 lw 2 pt 6 ps 1.5
set style line 3 lc 'green' lt 1 lw 2 pt 6 ps 1.5
Then, we can call the plot function on our inputFile:
plot 'inptFile' u 1:2 w lp ls 1, '' u 1:3 w lp ls 2, '' u 1:4 w lp ls 3
(u 1:2 stands for using 1:2 and means that we use the value in the first column as x-coordinate and the value in the second column as the y-coordinate. )
Note that our inputFile looks like this (i.e., each line contains a point's x and y-coordinate):
-1 2 3 4
0 1 2 4
1 2 4 16
2 3 16 8
Output:

Related

Line plot in GnuPlot where line width is a third column in my data file?

I have a datafile that has three columns :
1 1.0 1
2 1.5 2
3 0.0 3
4 1.2 2.5
5 1.0 1
6 1.1 5
where the first column is my X value, the second column is my Y value, and the third column is the line width. I'd like for each line segment to be plotted according to the third column line width.
I tried:
plot 'file1.dat' using 1:2:3 with lines lw var
But I get undefined variable: var error.
Is this possible in gnuplot?
Thanks.
If you define column 3 as the linewidth between points n and n+1 (so the value of col. 3 of the row will be ignored) you can cheat:
stat 'file1.dat'
n=STATS_records
plot for [i=0:0] 'file1.dat' using 1:2:(alma=$3) every ::i::i w l lc 1 lw 1
plot for [i=0:n-1] 'file1.dat' using 1:2:(alma=$3) every ::i::i+1 w l lc 1 lw alma notitle
OR
plot 'file1.dat' u 0:1
n=GPVAL_DATA_X_MAX
plot for [i=0:0] 'file1.dat' using 1:2:(alma=$3) every ::i::i w l lc 1 lw 1
plot for [i=0:n] 'file1.dat' using 1:2:(alma=$3) every ::i::i+1 w l lc 1 lw alma notitle
You need the first plot for[i=0:0] to 'initialize' variable 'alma'.
stat 'varwidth.dat' nooutput
n=STATS_records; prex=0; prey=0; SC=2 # How y-axis is expanded relative to the x-axis
plot for [i=0:n-1] for [try=0:1] '' using 1:((try==0?dx=$1-prex:1),(try==0?sl=($2-prey)/(dx==0?1:dx):1),(try==0?prex=$1:1),(try==0?prey=$2:1),$2+(w=$3/80*sqrt(1+(SC*sl)**2))/2):($2-w/2) every ::i::i+1 w filledcurves lc 1 notitle
This produces the correct line width (as opposed to the “line height”, as in the answer to a related question). I have no clue how to make the “lines” match where they join (seems to be impossible without support from inside gnuplot).
(This assumes that the data in the question is in a file varwidth.dat.)
As mentioned by #Christoph in the comments, you have N points (rows) and N linewidth values, but only N-1 connecting lines.
So, you have to decide which linewidth value should be applied to which line. Which one to skip? The first one or the last one? Here, the last one is skipped.
It's basically, a shortened version of #Tom Solid's solution. Actually, you can get the initial value already during the stats command.
As #Joce mentioned and #Ilya Zakharevich is suggesting in his answer, if you do not fear some extra effort you can also draw tapered lines.
Data:
# x y linewidth
1 1.0 1
2 1.5 2
3 0.0 3
4 1.2 2.5
5 1.0 1
6 1.1 5
Script: (works with gnuplot 4.6.0, March 2012)
### workaround for variable linewidth
reset
FILE = "SO/SO37925489.dat"
stats FILE u ((N=$0)==0?Lw0=$3:0) nooutput
set grid
plot for [i=0:N] FILE u 1:2:(Lw0=$3) every ::i::i+1 w l lw Lw0 lc rgb "red" notitle
### end of script
Result:

gnuplot highlighting points when with lines

I have 4 points I would like to plot using gnuplot, but with lines. The problem is, I can't find how to highlight these 4 points on the drawn line. I would like for the plot to be a line through the points, but that these points are also clearly marked. An example generated by excel. What I know is either drawing only points, or only a line with no highlighted points. Is a combination possible in gnuplot?
From gnuplot docs, define styles as:
set style line 1 lc rgb '#0060ad' lt 1 lw 2 pt 5 ps 1.5 # blue
set style line 2 lc rgb '#dd181f' lt 1 lw 2 pt 7 ps 1.5 # red
...
and plot:
plot ... w lp ls 1 # Use line style 1
where:
lc - linecolor
lt - linetype
lw - linewidth
pt - pointtype
ps - pointsize
w - with
lp - linespoints
ls - linestyle
or one line shorthand:
plot ... w lp lc rgb 'cyan' lw 2 pt 5
line style 1 will produce blue line with square points

Plot data points with connecting lines but which leave gaps

I like following linespoints plotting style:
http://www.gnuplotting.org/join-data-points-with-non-continuous-lines/
However, I have encountered an issue when I plot several lines with this style:
As you can see the second series of points blank-out also the first series (lines and points), what I don't want to happen.
Feature of gnuplot which makes this possible is pointinterval and pointintervalbox.
Documentation of gnuplot:
A negative value of pointinterval, e.g. -N, means that point symbols
are drawn only for every Nth point, and that a box (actually circle)
behind each point symbol is blanked out by filling with the background
color. The command set pointintervalbox controls the radius of this
blanked-out region. It is a multiplier for the default radius, which
is equal to the point size.
http://www.bersch.net/gnuplot-doc/set-show.html#set-pointintervalbox
Since the doc says, fill with background color I was hoping using a transparent background the issue could be resolved, but it seems to be that the color white is used.
Gnuplot version
gnuplot> show version long
G N U P L O T
Version 5.0 patchlevel 0 last modified 2015-01-01
Copyright (C) 1986-1993, 1998, 2004, 2007-2015
Thomas Williams, Colin Kelley and many others
gnuplot home: http://www.gnuplot.info
faq, bugs, etc: type "help FAQ"
immediate help: type "help" (plot window: hit 'h')
Compile options:
-READLINE +LIBREADLINE +HISTORY
-BACKWARDS_COMPATIBILITY +BINARY_DATA
+GD_PNG +GD_JPEG +GD_TTF +GD_GIF +ANIMATION
-USE_CWDRC +HIDDEN3D_QUADTREE
+DATASTRINGS +HISTOGRAMS +OBJECTS +STRINGVARS +MACROS +THIN_SPLINES +IMAGE +USER_LINETYPES +STATS +EXTERNAL_FUNCTIONS
Minimal Working Example (MWE):
gnuplot-space-line-mark-style.gp
reset
set terminal pngcairo transparent size 350,262 enhanced font 'Verdana,10'
show version
set output 'non-continuous_lines.png'
set border linewidth 1.5
set style line 1 lc rgb '#0060ad' lt 1 lw 2 pt 7 pi -1 ps 1.5
set style line 2 lc rgb '#0020ad' lt 1 lw 2 pt 7 pi -1 ps 1.5
set pointintervalbox 3
unset key
set ytics 1
set tics scale 0.75
set xrange [0:5]
set yrange [0:4]
plot 'plotting_data1.dat' with linespoints ls 1,\
'plotting_data2.dat' with linespoints ls 2
plotting_data1.dat
# X Y
1 2
2 3
3 2
4 1
plotting_data2.dat
# X Y
1.2 2.4
2 3.5
3 2.5
4 1.2
UPDATE
A working pgfplots solution is given on tex.stackoverflow.com
You can do a lot with gnuplot. It's just a matter of how complicated you allow it to get.
You can realize the gap by a two step plotting. First: only with points and second: with vectors which are lines between the points shortened by performing a bit of geometry calculations.
The parameter L1 determines the gap and needs to be adjusted to the data and graph scale. Tested with gnuplot 5.0 and 5.2.
Revised version:
Here is the version which creates gaps independent of the terminal size and the graph scale. It just requires bit more scaling. However, since it requires the size of terminal and graph which are stored in GPVAL_...-variables which you only get after plotting, therefere the procedure unfortunately requires replotting.
I'm not sure whether this works for all terminals. I just tested on a wxt terminal.
Empirical findings (for wxt-terminal on Win7):
pointsize 100 (ps) corresponds to 600 pixels (px), hence: Rpxps=6 (ratio pixel to pointsize )
term size 400,400 (px) corresponds to 8000,8000 terminal units (tu), hence: Rtupx=20 (ratio terminal units to pixels)
Edit: the factor Rtupx apparently is different for different terminals: wxt: 20, qt: 10, pngcairo: 1, you could use the variable GPVAL_TERM for checking the terminal.
Rtupx = 1. # for pngcairo terminal 1 tu/px
if (GPVAL_TERM eq "wxt") { Rtupx = 20. } # 20 tu/px, 20 terminal units per pixel
if (GPVAL_TERM eq "qt") { Rtupx = 10. } # 10 tu/px, 10 terminal units per pixel
The ratios of axis units (au) to terminal units (tu) are different for x and y and are:
Rxautu = (GPVAL_X_MAX-GPVAL_X_MIN)/(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN)
Ryautu = (GPVAL_Y_MAX-GPVAL_Y_MIN)/(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)
The variable GapSize is given in pointsize units. Actually, the real gap size depends on the pointsize (and also linewidth of the line). For simplicity, here gap size means the distance from the center of the point to where the line starts. So, GapSize=1.5 when having pointsize 1.5 will result in a gap of 0.75 on each side. L3(n) from the earlier version is now replaced by L3px(n) in pixel dimensions and L1 from the earlier version is not needed anymore.
Code:
### "linespoints" with gaps between lines and points
reset session
$Data1 <<EOD
# X Y
0 3
1 2
1.5 1
3 2
4 1
EOD
$Data2 <<EOD
0 0
1 1
2 1
2 2
3 1
3.98 0.98
EOD
GapSize = 1.5
Rtupx = 20. # 20 tu/px, 20 terminal units per pixel
Rpxps = 6. # 6 px/ps, 6 pixels per pointsize
# Ratio: axis units per terminal units
Rxautu(n) = (GPVAL_X_MAX-GPVAL_X_MIN)/(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN)
Ryautu(n) = (GPVAL_Y_MAX-GPVAL_Y_MIN)/(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)
dXpx(n) = (x3-x0)/Rxautu(n)/Rtupx
dYpx(n) = (y3-y0)/Ryautu(n)/Rtupx
L3px(n) = sqrt(dXpx(n)**2 + dYpx(n)**2)
x1px(n) = dXpx(n)*GapSize*Rpxps/L3px(n)
y1px(n) = dYpx(n)*GapSize*Rpxps/L3px(n)
x2px(n) = dXpx(n)*(L3px(n)-GapSize*Rpxps)/L3px(n)
y2px(n) = dYpx(n)*(L3px(n)-GapSize*Rpxps)/L3px(n)
x1(n) = x1px(n)*Rtupx*Rxautu(n) + x0
y1(n) = y1px(n)*Rtupx*Ryautu(n) + y0
x2(n) = x2px(n)*Rtupx*Rxautu(n) + x0
y2(n) = y2px(n)*Rtupx*Ryautu(n) + y0
set style line 1 pt 7 ps 1.5 lc rgb "black"
set style line 2 lw 2 lc rgb "black
set style line 3 pt 7 ps 1.5 lc rgb "red"
set style line 4 lw 2 lc rgb "red"
plot \
$Data1 u (x3=NaN, y3=NaN,$1):2 w p ls 1 notitle, \
$Data1 u (y0=y3,y3=$2,x0=x3,x3=$1,x1(0)):(y1(0)): \
(x2(0)-x1(0)):(y2(0)-y1(0)) w vectors ls 2 nohead notitle, \
$Data2 u (x3=NaN, y3=NaN,$1):2 w p ls 3 notitle, \
$Data2 u (y0=y3,y3=$2,x0=x3,x3=$1,x1(0)):(y1(0)): \
(x2(0)-x1(0)):(y2(0)-y1(0)) w vectors ls 4 nohead notitle
replot
### end of code
Result: (two different terminal sizes)
Explanations:
Question: Why is there the argument (n) for L3(n), x1(n), y1(n), x2(n), y2(n)?
n is always 0 when L3(n),... are computed and is not used on the right hand side.
Answer:
To make them non constant-expressions. Alternatively, one could
add x0,x3,y0,y3 as variables, e.g. L3(x0, y0, x3, y3); however, the
compactness would be lost.
Question: What does the using part in plot $Data1 using (x3=NaN,y3=NaN,$1):2 mean?
Answer:
(,) is called a serial evaluation which is documented under the
section Expressions > Operator > Binary in the gnuplot documentation
(only v4.4 or newer).
Serial evaluation occurs only in parentheses and is guaranteed to
proceed in left to right order. The value of the rightmost subexpression
is returned.
This is done here for the initialialization of (x3,y3) for the
subsequent plot of the line segments as vectors. It is irrelevant for
the plotting of points.
Question: How does this draw N-1 segments/vectors for N points?
Answer:
Setting x3=NaN, y3=NaN when plotting points ensures that for the
first data point the initial data point (x0,y0) is set to (NaN,NaN)
which has the consequence that the evaluation of x1(0) and y1(0) also returns NaN.
Gnuplot in general skips points with NaN, i.e. for the first
data point no vector is drawn. The code draws the line between the
first and second point when the iteration reaches the second point.
Question: How does the second plot '' u ... iterates over all points?
Answer:
gnuplot> h special-filenames explains this:
There are a few filenames that have a special meaning: '', '-', '+' and '++'.
The empty filename '' tells gnuplot to re-use the previous input file in the
same plot command. So to plot two columns from the same input file:
plot 'filename' using 1:2, '' using 1:3
Question: Do we need the parentheses around (y1(0))?
Answer: gnuplot> h using explains this:
Each may be a simple column number that selects the value from one
field of the input file, a string that matches a column label in the first
line of a data set, an expression enclosed in parentheses, or a special
function not enclosed in parentheses such as xticlabels(2).

How to change thickness of a single in line in EXISTING plot

I create a plot with many (50+) lines on it.
I would like to set up a keybind such that I can toggle through each line and change it's thickness, and so making that line stand-out from the rest, then when I press the key again, the next line becomes thicker.
That way I can examine each line clearly, next to the others.
I know how to assign keys, but I don't know how to change the thickness of an exiting line on an existing plot.
How can I go about this?
Moon
EDIT 1
Is it possible to do something like this:
set style line 1 lt 2 lc rgb "red" lw 3
set style line 2 lt 2 lc rgb "orange" lw 2
set style line 3 lt 2 lc rgb "yellow" lw 3
set style line 4 lt 2 lc rgb "green" lw
savedls1 = ls 1
savedls2 = ls 2
savedls3 = ls 3
savedls4 = ls 4
plot <whatever> ls 2 #Original style
set style line 2 lt 2 lc rgb "black" lw 2 #new temp style
plot <whatever> ls 2; replot #Temp new style
set style line 2 savedls2
plot <whatever> ls 2; replot #Back to original style
In the command line (v4.6 patchlevel 3), you can do it like this:
Specify a line style:
set style line 1 lt 2 lw 2 pt 3 ps 0.5
When plotting, specify this line style:
plot sin(x) ls 1
Now, you can change this line style, e.g. changing the line width:
set style line 1 lt 2 lw 4 pt 3 ps 0.5
A simple replot will produce the same graph with the updated line style.
EDIT
Christoph provided this information in a comment, addressing the question of a key-bind:
It is enough in step 3 to change the linewidth, the rest remains unchanged:
set style line 1 lw 4
That would allow you to define two different linewidths and toggle between them:
lw_small = 2
lw_thick = 5
set style line 1 lt 2 lw lw_small pt 3 ps 0.5
plot sin(x) ls 1
set style line 1 lw lw_thick # here, everything but the line-width stays constant
pause 3
replot
set style line 1 lw lw_small
pause 3
replot

Skipping empty files in Gnuplot

I am using gnuplot 4.6. Also, I know that a similar question was asked more than a year ago here. The answer to that requires to write a small bash script. I want to know if it is possible to achieve this from within gnuplot script, especially when gnuplot-4.6 has so many cool features added. I am trying to achieve something like this :
set xrange[xL:xU]
set yrange[yL:yU]
plot "file1.dat" using 1:2 w l lt 1 lw 1 lc 3,\
"file2.dat" using 1:2 w l lt 1 lw 1 lc 3
I am repeating the above process in a loop and the xrange & yrange parameters are being updated in each iteration. Also, I am saving the output of each iteration as some image file. Now, file2.dat is guaranteed to have some points in all iterations. BUT this is NOT true for file1.dat. Hence, I want gnuplot to skip plotting the file1.dat in case it is empty. Please note, that it is PERFECTLY OK in my case if no points are plotted from file1.dat.
This can be achieved easily using an if statement, provided there is some command in gnuplot to detect if a file has no points, without trying to plot it. In that case, the above code will look something like this :
set xrange[xL:xU]
set yrange[yL:yU]
if ("file.dat" not empty){
plot "file1.dat" using 1:2 w l lt 1 lw 1 lc 3,\
"file2.dat" using 1:2 w l lt 1 lw 1 lc 3
}else {
plot "file2.dat" using 1:2 w l lt 1 lw 1 lc 3
}
Please help me formulate the 'condition' of the aforementioned if statement.
Thanks & Cheers
Abhinav
I could not find any hack that used only gnuplot commands. As a result, I am posting a work around which takes the help of shell to find if file1.dat has any any lines of data or not.
The condition in the gnuplot script file will look like :
if(system("awk '{x++}END{ print x}' file1.dat")>0){
plot "file1.dat" using 1:2 w l lt 1 lw 1 lc 3,\
"file2.dat" using 1:2 w l lt 1 lw 1 lc 3
}else{
plot "file2.dat" using 1:2 w l lt 1 lw 1 lc 3
}
I still would be grateful if anyone can give me a gnuplot command only method.

Resources