Contour plot on triangular domain - plot

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 ?

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

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

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)

Gnuplot: Making pm3d palette repeat when out of range

The plan is to plot the phase of a 2D-complex function using pm3d map and a repeating color-palette in a continous way. To be more specific, the palette is only defined on [-pi, pi], while the phase itself might run out of this range. The color-palette shall repeat for those values.
My current attempt was to force the function to stay inside the range and start over from the other side when crossing a border by subtracting or adding multiples of 2*pi.
This, however, resulted in artifacts whenever such a phase-jump occured in the function. Note those blue-ish pixel-rings in the plot:
This was the code used to generate this plot:
set pm3d map
set palette model HSV defined ( 0 0 1 1, 1 1 1 1 )
set samples 100; set isosamples 100
set xrange [-4:4]
set yrange [-4:4]
set cbrange [-pi:pi]
set cblabel "Phase"
phaseCont(u,v) = 2*pi* ((u/4)**2 + (v/4)**2)
phaseClip(u,v) = phaseCont(u,v) - (floor(phaseCont(u,v)/(2*pi) + 0.5) * 2*pi)
set terminal png
set output "phaseplot.png"
splot phaseClip(x,y) with pm3d
unset output
It makes sense the artifacts appear as interpolation happens, but it's not what I'm going for, of course.
Is there a way to create beautiful 2D-plots with repeating color-patterns?
Gnuplot cannot define infinitey repeating color palettes. In your case, the disturbing interpolation comes from the default pm3d interpolation, which calculates the average of all four corners to determine the color (see show pm3d).
To avoid that kind of interpolation use e.g.
set pm3d corners2color c1
to determine the color from one corner only. Especially in your case that shouldn't matter, because you can always increase the sampling of your function to get smoother results:
set pm3d map
set palette model HSV defined ( 0 0 1 1, 1 1 1 1 )
set samples 500; set isosamples 500
set xrange [-4:4]
set yrange [-4:4]
set cbrange [-pi:pi]
set pm3d corners2color c1
set cblabel "Phase"
phaseCont(u,v) = 2*pi* ((u/4)**2 + (v/4)**2)
phaseClip(u,v) = phaseCont(u,v) - (floor(phaseCont(u,v)/(2*pi) + 0.5) * 2*pi)
set terminal pngcairo
set output "phaseplot.png"
splot phaseClip(x,y) with pm3d

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