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?
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…