Reputation: 25749
I tried to get contour lines on data which is not "evenly" distributed within a rectangular bounding box.
In order to get this I needed to play several tricks.
I had to unset dgrid3d
, otherwise I could not plot the data as it is. Furthermore, I had to plot the contour lines into a table to be able to plot the contour when dgrid3d
is off.
The code below is a bit cumbersome, but the result would be more or less ok, if the levels of the contour lines were correct.
In the below example they levels should go up to 2500, not just to 1200.
Code:
### wrong contour line levels with "non-rectangular" data
reset session
# create some test data
set print $Data
do for [i=0:100] {
do for [j=0:100-i:5] {
print sprintf("%g %g %g",i,j,i*j)
}
print ""
}
set print
set pm3d
set view map
# get contour lines into table
set contour
set dgrid3d
set dgrid3d 20,20
set cntrparam levels auto 20
set table $Contour
splot $Data u 1:2:3
unset table
unset contour
unset dgrid3d
# only use the contourlines, skip grid data at index 0
set table $Contour2
splot $Contour u 1:2:3 index 1::1
unset table
# convert one empty line into two empty lines, otherwise splot will connect the lines
set print $Contour # overwrite datablock $Contour
do for [i=1:|$Contour2|] {
if ($Contour2[i] eq '') { print ""}
print $Contour2[i]
}
set print
stats $Contour2 u 0 nooutput # get number of blocks = number of contour lines
ContourLineCount = STATS_blocks
# get contour line values into array
array ContValues[ContourLineCount]
set table $Dummy
plot for [i=0:ContourLineCount-1] $Contour u (ContValues[i+1]=$3) index i every ::0::0 w table
unset table
set key noautotitle horizontal at screen 0.15,0.9
set size ratio -1
set lmargin screen 0.10
set rmargin screen 0.85
splot $Data u 1:2:3 w pm3d, \
for [i=0:ContourLineCount-1] $Contour u 1:2:3:3 index i w l lw 1.5 lc i, \
for [i=1:ContourLineCount] keyentry w l lw 1.5 lc i title sprintf("%g",ContValues[i])
### end of code
Result:
Checking the documentation, I assume that gnuplot needs more or less equally distributed data within a rectangular bounding box. So, in the above case, although the contour lines look somehow reasonable, but the levels are nonsense.
From help contour
:
set contour enables contour drawing for surfaces. This option is available for splot only. It requires grid data, see grid_data for more details. If contours are desired from non-grid data, set dgrid3d can be used to create an appropriate grid.
From help dgrid3d
:
When enabled, 3D data read from a file are always treated as a scattered data set. A grid with dimensions derived from a bounding box of the scattered data and size as specified by the row/col_size parameters is created for plotting and contouring. The grid is equally spaced in x (rows) and in y (columns); the z values are computed as weighted averages or spline interpolations of the scattered points' z values. In other words, a regularly spaced grid is created and the a smooth approximation to the raw data is evaluated for all grid points. This approximation is plotted in place of the raw data.
Questions:
Is there maybe nevertheless a way to get the correct contour line levels? I don't think I can simply multiply the levels by a factor of 2 (this would be more or less the expected levels). Maybe mirroring the data, getting the levels and removing the mirrored data again? Maybe someone can even simplify the code getting the desired result?
Upvotes: 1
Views: 749
Reputation: 15093
I think all those extra steps to massage the data format and create a separate block of contour line data are totally unnecessary.
The fundamental problem here is that your data is not just "uneven"; it is dense over half the area being plotted but entirely missing for the other half. What are the "correct contour lines" for a region in which there is no data whatsoever?
What you need is either
or
Gnuplot does not provide an easy way to produce a plot that is a triangle rather than a rectangle, but filling half the rectangle with background color is not hard.
# create some test data
set print $Data
do for [i=0:100] {
do for [j=0:100-i:5] {
print sprintf("%g %g %g",i,j,i*j)
}
}
unset print
set dgrid3d 20,20 gauss
set view map
set size ratio -1
set key outside
set contour
set cntrparam levels auto 20
set cntrlabel format "%.0f"
set obj 1 polygon from graph 0,1 to graph 1,1 to graph 1,0
set obj 1 front fillstyle solid noborder fillcolor "white"
splot $Data u 1:2:3 w lines nosurface title '$Data'
Upvotes: 1