首页 > 解决方案 > gnuplot:如何使用“不均匀”数据获得正确的等高线水平值?

问题描述

我试图在矩形边界框内不“均匀”分布的数据上获取等高线。为了得到这个,我需要玩几个技巧。我必须这样做unset dgrid3d,否则我无法按原样绘制数据。此外,我必须将等高线绘制到表格中,以便能够在dgrid3d关闭时绘制等高线。下面的代码有点麻烦,但如果等高线的水平正确,结果或多或少都可以。在下面的例子中,他们的水平应该上升到 2500,而不仅仅是 1200。

代码:

### 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

结果:

在此处输入图像描述

检查文档,我假设 gnuplot 在矩形边界框中需要或多或少均匀分布的数据。所以,在上面的例子中,虽然等高线看起来有些合理,但层次是无稽之谈。

来自help contour

set contour 启用曲面的等高线绘制。此选项仅适用于 splot。它需要网格数据,有关详细信息,请参阅 grid_data。如果需要非网格数据的等高线,可以使用 set dgrid3d 创建合适的网格。

来自help dgrid3d

启用后,从文件中读取的 3D 数据始终被视为分散数据集。创建一个网格,其尺寸源自分散数据的边界框和由 row/col_size 参数指定的大小,用于绘图和轮廓绘制。网格在 x(行)和 y(列)中等距分布;z 值计算为散点 z 值的加权平均值或样条插值。换句话说,创建了一个规则间隔的网格,并对所有网格点评估原始数据的平滑近似。这个近似值被绘制在原始数据的位置。

问题:

有没有办法获得正确的等高线水平?我认为我不能简单地将水平乘以 2 倍(这或多或少是预期水平)。也许镜像数据,获取级别并再次删除镜像数据?也许有人甚至可以简化代码以获得所需的结果?

标签: gnuplot

解决方案


我认为所有这些额外的步骤来处理数据格式和创建一个单独的轮廓线数据块是完全没有必要的。

这里的根本问题是您的数据不仅仅是“不均匀”;它在被绘制区域的一半以上是密集的,但另一半则完全缺失。对于没有任何数据的区域,“正确的等高线”是什么?

你需要的是要么

  1. 缺失区域的数据(如果只是不完整的话)

或者

  1. 某种方式仅绘制您拥有数据的区域

Gnuplot 没有提供一种简单的方法来生成三角形而不是矩形的绘图,但是用背景色填充一半的矩形并不难。

# 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'

在此处输入图像描述


推荐阅读