Gnuplot: splot with data-file only containing x and b(x) - plot

I want to plot the contour of the following function:
f(x,y)=y³*b(x)
My data-file looks something like this:
x b(x)
-1 10.123
-0.995 10.112
-0.99 10.100
I am not sure how to make the right splot command as my datafile does not look like (x y z).
Thats my script so far:
reset
f(x,y)=y³*b(x)
set xrange [-6:6]
set yrange [-5:5]
set isosamples 50
set table 'test.dat'
splot 'Data.dat' u 1:(b(x)=$2, f(x,y)) -------------------------?
unset table
set contour base
set cntrparam bspline
set cntrparam levels incremental -0.1,0.02,0.1
unset surface
set table 'contour.dat'
splot 'Data.dat' u 1:(b(x)=$2, f(x,y)) -------------------------?
unset table
reset
set xrange [-6:6]
set yrange [-5:5]
unset key
set palette rgbformulae 33,13,10
plot 'test.dat' with image, 'contour.dat' w l lt -1 lw 1.5

Creating a 3D surface directly from the data in your file will not work because their is no y coordinate data. The program knows how to plot data and it know how to plot functions but you have to choose one or the other.
To treat the plot as a data plot you will need to expand the file to contain x/y/z data (see 'help matrix'). This is probably easier to do outside of gnuplot.
Alternatively you can recast your function b(x) in some analytic form, possibly by using gnuplot's "fit" command and your existing data file. Suppose for example that a quadratic fit to your data is sufficient:
b(x) = C0 + C1*x + C2*x*x + C3*x*x*x
C0=C1=1; C2=C3=0;
fit b(x) 'test.dat' using 1:2 via C0,C1,C2,C3
Now you have analytic forms for both the x and y dependence of the surface to be contoured
f(x,y) = b(x) * y*y*y
set contour base
set cntrparam bspline
set cntrparam levels incremental -0.1,0.02,0.1
unset surface
splot f(x,y)

Related

How to add contour lines to a heat map

I have a script which takes data (formatted in 3 columns x,y,z) and gives a heat map:
set logscale x 10
set yrange [1e-9:2e-8]
set xlabel "x"
set ylabel "y"
set multiplot
plot 'filetest.dat' u 1:2:9 with image
This is a 2D heat map, shown below:
All I want to do is add contours to this plot, at some z values such as -20 to -8 in in intervals of 2. Unfortunately, none of the answers I've found have been able to help me with this. Any help would be greatly appreciated.
Although there are a lot of examples about contour on www.gnuplot.info, I couldn't find your exact case, because the examples are with functions, not with datablocks or data files (well, it should be similar).
The following code does what you're asking for, but the construct '' u 1:2:3:("") w labels for adding labels still looks strange to me and doesn't allow for plotting boxed labels.
In gnuplot console check help contour and help cntrparam.
Code:
### pm3d with contour lines
reset session
set view equal xyz
# create some test data
set samples 40
set isosamples 40
set table $Data
splot '++' u 1:2:($1*$2/2-9)
unset table
set view map
set contour base
set cntrparam levels incremental -20,2,-8
set cntrlabel font ",10"
set xrange[-5:5]
set yrange[-5:5]
splot $Data u 1:2:3 w pm3d notitle, '' u 1:2:3:("") w labels notitle
### end of code
Result:
Addition:
Here is another approach with plot w image instead of splot w pm3d.
Although still not fully satisfying with the white label boxes on top of the contour lines. Adding an offset to the labels will not work for all labels at the same time. I'm not sure whether there is a way to just interrupt the contour lines for the labels.
Code:
### heatmap with contour lines
reset session
set view equal xyz
# create some test data
set samples 40
set isosamples 40
set table $Data
splot '++' u 1:2:($1*$2/2-9)
unset table
set view map
set contour base
set cntrparam levels incremental -20,2,-8
set cntrlabel font ",10"
set xrange[-5:5]
set yrange[-5:5]
set style textbox noborder opaque
# put contour lines in a separate datablock
unset surface
set table $Contour
splot $Data u 1:2:3
unset table
plot $Data u 1:2:3 w image notitle, \
$Contour u 1:2 w l lw 2 lc "black" not, \
'' u 1:2:3 every 40::3 w labels boxed notitle
### end of code
Result:
Addition 2:
Another variation with colored contour lines and key instead of labels. This seems to be a bit cumbersome, I hope there is a simpler solution for this.
Code:
### heatmap with colored contour lines
reset session
set view equal xyz
# create some test data
set samples 40
set isosamples 40
set table $Data
splot '++' u 1:2:($1*$2/2-9)
unset table
set view map
set contour base
set cntrparam levels incremental -20,2,-8
set xrange[-5:5]
set yrange[-5:5]
set style textbox noborder
# put contour lines in a separate datablock
unset surface
set table $Contour
splot $Data u 1:2:3
unset table
# get contour levels unique and in sorted order
set table $Dummy
plot $Contour u 3 w table
unset table
set table $ContourSorted
plot $Dummy u 1 smooth freq
unset table
print $ContourSorted
set key out right Left
plot $Data u 1:2:3 w image notitle, \
for [i=0:*] $Contour u 1:2:3 index i w l lw 2 lc i+1 not, \
for [i=|$ContourSorted|-2:5:-1] $ContourSorted u (NaN):1 w l lw 2 lc |$ContourSorted|-i-1 ti word($ContourSorted[i],1)
### end of code
Result:

splot with mixing data and parameter

I have two curves as data points (i. e. a two sets of two-tuples). I want to splot the surface of their weighted sum, the weight being the third axis (so like a smooth transition from one curve to the other).
Example: If I have the functions sin(x) and x**2 / 100, I can achieve it like this:
set isosamples 100
splot [-10:10] [0:1] y * sin(x) + (1-y) * (x**2 / 100)
In my case, however, I do not have functions but values from a data file and I do not know how to combine this with an automatic running value like the weight y in the example above. I tried, e.g. this, but it did not work:
splot [] [0:1] 'datafile' using 1:(y):(y * $2 + (1-y) * $3)
The error I get is undefined variable: y (which is clear). I just don't know how to combine data from a data file and a running parameter.
The first idea which comes to my mind is to plot the "mixed" data into a table. I hope that there are better approaches.
Code:
### mixing of parameter and data
reset session
# create some test data
set table $Data
plot '+' u 1:(sin($1)):($1**2/100.) w table
unset table
N = 20.0 # float number to avoid integer division
set table $Mix
do for [i=0:N] {
plot $Data u 1:(i/N):(i/N*$2 + (1-i/N)*$3) w table
plot '+' u ("") every ::0::0 w table # plot "empty line" to disconnect lines
}
unset table
set view 48,9
set ztics 0.5
splot $Mix u 1:2:3 w l
### end of code
Result:
If you need only a smooth transition, you can use dgrid3d
set table $Data
plot '+' u 1:($1**2/100.) w table
plot '+' u ("") every ::0::0 w table # plot "empty line" to disconnect lines
plot '+' u 1:(sin($1)) w table
unset table
set view 48,9
set ticslev 0
set dgrid3d 20,100 splines
splot $Data us 1:-1:2 w l
The pseudocolumn -1 indexes the data set.
If your x data are uniform sampled, you can simplify this to
set table $Data
plot '+' u ($1**2/100.):(sin($1)) w table
unset table
set dgrid3d 20,100 splines
splot $Data matrix us ($2/10-5):1:3 w l

Contour plot on triangular domain

I have to plot a data file which is in a triangular domain. To make it clearer, my data file possess 3 value, two frequencies f1 and f2 with a sum lower or equal to 100 (i.e. f1 + f2 <= 100) and a metric m. My data file is structured as follow:
f1 f2 m
0 0 x1
...
0 100 xn
5 0 xn+1
...
100 0 xm
...
100 100 xm+n
with a blank line each time f1 changes. I plot a view map with a colorbox representing the metric m. Here is a minimal example:
set view map scale 1
set style data pm3d
set pm3d ftriangles
set xrange [0:100]
set yrange [0:100]
splot 'datafile.dat' u 1:2:3
Given the following result
To plot the contour plot of this map, I use the following script:
set view map scale 1
unset surface
set style data lines
set dgrid3d
set contour both
set xrange [0:100]
set yrange [0:100]
set cntrparam levels auto 23
splot 'datafile.dat' u 1:2:3
I got the following image:
As we can see, a part of the contour plot is above the line f(x)=100-x which shouldn't happen due to the constraint f1 + f2 <= 100.
So, here is my question: is there a way to hide the lines' parts which are above the line f(x)=100-x ?

Gnuplot , pm3d with contour lines

i am 3d plotting a matrix with some values, and i need to add contour lines to the plot, is there a simple gnuplot command to do this?
I tried the command: "set contour base" but only 1 line came up, i think it should be many lines. See matlab picture
When i plot it in gnuplot i only get 1 contour line in the top left corner.But everything else is correct.
My goal is to get it to look like in matlab like this Matlabplot
I also found this example: see link in comments (dont have enough rep), but i dont understand where i should put in the data values from test.txt
test.txt
test.txt
gnuplot commands
set view map
set yrange [0:30]
set xrange [0:30]
set dgrid3d 100,100,4
set contour base
splot 'test.txt' u 1:2:3 w pm3d
What you are missing is to tell gnuplot where to put the contours. This is done via the set cntrparam levels incr -0.3,0.1,0.5 command which means: start at -0.3 and trace a contour every o.1 up to 0.5.
AFAIK if you want to make contours all black, you have to save the contour lines in a temporary file (here contour.txt).
So your script would be
reset
set contour
unset surface
set cntrparam levels incr -0.3,0.1,0.5
set view map
set xrange [0:30]
set yrange [0:30]
set dgrid3d 100,100,4
set table "contour.txt"
splot 'test.txt'
unset table
unset contour
set surface
set table "dgrid.txt"
splot 'test.txt'
unset table
reset
set pm3d map
unset key
set palette defined (0 '#352a87', 1 '#0363e1',2 '#1485d4', 3 '#06a7c6', 4 '#38b99e', 5 '#92bf73', 6 '#d9ba56', 7 '#fcce2e', 8 '#f9fb0e')
set autoscale fix
set grid
splot 'dgrid.txt' w pm3d, 'contour.txt' w l lc rgb "black"
which gives you this:
Note:
you can get rid of interpolation file (dgrid.txt) if you format a bit your datafile by leaving a blank line after each row (i.e. every 30 datapoints) because they are already mesh-ordered.
This could be done also with a awk script. But I'm too lazy to look into it...
The rest will remain the same and will work as expected.
here is how it should look like :
In which case the script would simply become:
set pm3d map impl
set contour
set style increment user
do for [i=1:18] { set style line i lc rgb "black"}
set cntrparam levels incr -0.3,0.1,0.5
set palette defined (0 '#352a87', 1 '#0363e1',2 '#1485d4', 3 '#06a7c6', 4 '#38b99e', 5 '#92bf73', 6 '#d9ba56', 7 '#fcce2e', 8 '#f9fb0e')
set autoscale fix
splot 'test.txt' w pm3d notitle
with no need of ntermediate file and with better contour since data in not interpolate by gridded:

Making data files with gnuplot

I am new to gnuplot. I am trying to plot 3d vector fields. I know that I have to create a data file that has six columns representing x, y, z, deltax,deltay, deltaz.
I wondering if it is possible to define a function f(x,y,z) and have gnuplot create the data file I desire in order to plot the vectors.
If so, how do I go about doing this?
You can use the special file name ++ to create a 2d grid on which you can define you vector field:
set xrange [-10:10]
set yrange [-10:10]
set samples 100
set isosamples 100
vx(x,y,z) = ...
vy(x,y,z) = ...
vz(x,y,z) = ...
z(x,y) = ...
splot '++' using 1:2:(z($1,$2)):(vx($1,$2,z($1,$2))):(vy($1,$2,z($1,$2))):(vz($1,$2,z($1,$2))) with vectors
This plots a vector field (vx,vy,vz) on the surface z(x,y). Gnuplot cannot generate a 3d grid.
You could try to simulate such a real 3d vector field with a loop:
z(i) = -10 + i*(20.0/99.0)
splot for [i=1:100] '++' using 1:2:(z(i)):(vx($1,$2,z(i))):(vy($1,$2,z(i))):(vz($1,$2,z(i))) with vectors lt 1
As example considert the following script for a central force:
lim = 2
N = 6
set xrange [-lim:lim]
set yrange [-lim:lim]
set zrange [-lim:lim]
set samples N
set isosamples N
sc= 0.3
r(x,y,z) = sqrt(x**2 + y**2 + z**2)
gx(x,y,z) = sc/(x**2 + y**2 + z**2) * x/r(x,y,z)
gy(x,y,z) = sc/(x**2 + y**2 + z**2) * y/r(x,y,z)
gz(x,y,z) = sc/(x**2 + y**2 + z**2) * z/r(x,y,z)
z(i) = -lim + 2*i*lim/(N - 1.0)
unset key
set xyplane 0
splot for [i=1:N] '++' using 1:2:(z(i)):(gx($1,$2,z(i))):(gy($1,$2,z(i))):(gz($1,$2,z(i))) with vectors lt 1
with the output
Here an answer that would apply to a 3d surface plot. I'm sure this can be expanded to work for a vector field as well - a matter of writing the function which is outside my comfort zone.
You would plot your function to a table rather than a graphic output and then plot the graph using the table you just have produced (and could inspect, edit etc. before). Sample:
# output to a file with the data
set table "so.dat"
# plot your function
splot [-2:2][-2:2] exp(-(x**2 + y**2))*cos(x/4)*sin(y)*cos(2*(x**2+y**2))
# switch the graphic screen on again and plot from your file
unset table
unset ztics # avoiding cluttered ztics
splot "so.dat" u 1:2:3 w l
yields
Sample taken from Philipp K. Janert, Gnuplot In Action

Resources