gnuplot等高线图阴影线

for*_*ter 6 gnuplot contour

我正在使用gnuplot绘制多个函数的轮廓图。这是为了优化问题。我有3个功能:

  1. f(x,y)
  2. g1(x,y)
  3. g2(x,y)

两者g1(x,y)g2(x,y)都是约束条件,想在的等高线图上绘制f(x,y)

这是教科书示例:

在此处输入图片说明

感谢@theozh,这是我在gnuplot中复制它的尝试。

### contour lines with labels
reset session

f(x,y)=(x**2+y-11)**2+(x+y**2-7)**2
g1(x,y)=(x-5)**2+y**2
g2(x,y) = 4*x+y

set xrange [0:6]
set yrange [0:6]
set isosample 250, 250
set key outside

set contour base
set cntrparam levels disc 10,30,75,150,300,500,850,1500 
unset surface
set table $Contourf
    splot f(x,y)
unset table

set contour base
set cntrparam levels disc 26
unset surface
set table $Contourg1
    splot g1(x,y)
unset table

set contour base
set cntrparam levels disc 20
unset surface
set table $Contourg2
    splot g2(x,y)
unset table

set style textbox opaque noborder

set datafile commentschar " "
plot for [i=1:8] $Contourf u 1:2:(i) skip 5 index i-1 w l lw 1.5 lc var title columnheader(5)
replot $Contourg1 u 1:2:(1) skip 5 index 0 w l lw 4 lc 0 title columnheader(5)
replot $Contourg2 u 1:2:(1) skip 5 index 0 w l lw 4 lc 0 title columnheader(5)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

我想在gnuplot示例中复制教科书图片。如何在函数g1g2上绘制阴影线,如上图所示。

@theozh提供了以下出色的解决方案。但是,该方法不适用于陡峭曲线。举个例子

reset session
unset key

set size square

g(x,y) = -0.8-1/x**3+y

set xrange [0:4]
set yrange [0:4]
set isosample 250, 250
set key off

set contour base
unset surface

set cntrparam levels disc 0
set table $Contourg
    splot g(x,y)
unset table

set angle degree
set datafile commentschar " "

plot $Contourg u 1:2 skip 5 index 0 w l lw 2 lc 0 title columnheader(5)

set style fill transparent pattern 4
replot $Contourg u 1:2:($2+0.2) skip 5 index 0 w filledcurves lc 0 notitle 
Run Code Online (Sandbox Code Playgroud)

产生下图。有没有办法使用不同的偏移量,例如x <1.3和x> 1.3偏移y值的偏移x值。这将产生更好的填充曲线。我正在寻找的东西的matlab实现可以在这里找到:https : //www.mathworks.com/matlabcentral/fileexchange/29121-hatched-lines-and-contours

在此处输入图片说明

在重复@Ethans程序中,我得到以下信息,与@Ethan相比,dashtype相对较粗,不确定为什么,我使用gnuplot v5.2和wxt终端。

在此处输入图片说明

当我复制@theozh代码时,除了闭合轮廓外,它工作得很好,不知道为什么吗?参见以下示例:

f(x,y)=x*exp(-x**2-y**2)+(x**2+y**2)/20
g1(x,y)= x*y/2+(x+2)**2+(y-2)**2/2-2

set xrange [-7:7]
set yrange [-7:7]
set isosample 250, 250
set key outside

set contour base
unset surface

set cntrparam levels disc 4,3.5,3,2.5,2,1.5,1,0.5,0 
set table $Contourf
    splot f(x,y)
unset table

set cntrparam levels disc 0
set table $Contourg1
    splot g1(x,y)
unset table

# create some extra offset contour lines
# macro for setting contour lines
ContourCreate = '\
    set cntrparam levels disc Level; \
    set table @Output; \
        splot @Input; \
    unset table'

Level = 0.45
Input = 'g1(x,y)'
Output = '$Contourg1_ext'
@ContourCreate


# Macro for ordering the datapoints of the contour lines which might be split
ContourOrder = '\
stats @DataIn skip 6 nooutput; \
N = STATS_blank-1; \
set table @DataOut; \
    do for [i=N:0:-1] { plot @DataIn u 1:2 skip 5 index 0 every :::i::i with table }; \
unset table'

DataIn = '$Contourg1'
DataOut = '$Contourg1_ord'
@ContourOrder

DataIn = '$Contourg1_ext'
DataOut = '$Contourg1_extord'
@ContourOrder


# Macro for reversing a datablock
ContourReverse = '\
set print @DataOut; \
    do for [i=|@DataIn|:1:-1] { print @DataIn[i]}; \
set print'

DataIn = '$Contourg1_extord'
DataOut = '$Contourg1_extordrev'
@ContourReverse

# Macro for adding datablocks
ContourAdd = '\
set print @DataOut; \
    do for [i=|@DataIn1|:1:-1] { print @DataIn1[i]}; \
    do for [i=|@DataIn2|:1:-1] { print @DataIn2[i]}; \
set print'

DataIn1 = '$Contourg1_ord'
DataIn2 = '$Contourg1_extordrev'
DataOut = '$Contourg1_add'
@ContourAdd


set style fill noborder 
set datafile commentschar " "
plot \
    for [i=1:8] $Contourf u 1:2:(i) skip 5 index i-1 w l lw 1.5 lc var title columnheader(5), \
    $Contourg1 u 1:2 skip 5 index 0 w l lw 2 lc 0 title columnheader(5), \
    $Contourg1_add u 1:2 w filledcurves fs transparent pattern 5 lc rgb "black" notitle
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

the*_*ozh 2

这是您(和我)所希望的解决方案。\n您只需将填充参数输入数据块:TiltAngle以度为单位(>0\xc2\xb0:左侧,<0\xc2\xb0 路径方向右侧) ,HatchLengthHatchGap以像素为单位。该过程变得有点冗长,但它满足了您的要求。wxt我已经使用 gnuplot 5.2.8 和 5.4.1以及终端对其进行了测试qt

\n

该过程的基本作用是:

\n
    \n
  1. 确定数据输入曲线的两个连续点之间的角度
  2. \n
  3. 根据以下公式沿曲线插值数据点HatchSeparation
  4. \n
  5. 缩放与图形比例和终端大小无关的所有内容(但是,这需要没有剖面线的曲线虚拟图来获取 gnuplot 变量GPVAL_X_MAX, GPVAL_X_MIN, GPVAL_TERM_XMAX, GPVAL_TERM_XMIN, GPVAL_Y_MAX, GPVAL_Y_MIN, GPVAL_TERM_YMAX, GPVAL_TERM_YMIN.
  6. \n
\n

限制:

\n
    \n
  • 不适用于对数轴
  • \n
  • 多个独立的路径需要用两个空行分隔
  • \n
  • 如果您将其与等高线一起使用,则必须确保等高线数据点的顺序正确(请参阅我的第一个答案中的评论)。此外,gnuplot 可能会生成用单个空线分隔的轮廓线。如果我有时间或/和有人要求的话,我可以解决这个问题。
  • \n
\n

编辑:( 完全修订版)

\n

之前的脚本(在我看来)相当混乱且难以遵循(尽管没有人抱怨;-)。我删除了对子过程的调用,从而删除了子过程中变量的前缀,并将所有内容放入一个脚本中,测试数据生成除外。

\n

享受孵化线条的乐趣!欢迎提出意见和改进!

\n

测试数据生成: SO57118566_createTestData.gp

\n
### Create some circle test data\n\nFILE = "SO57118566.dat"\nset angle degrees\n\n# create some test data\n# x     y     r     a0  a1    N\n$myCircleParams <<EOD\n 1.0    0.3   0.6   0   360   120\n 2.4    0.3   0.6   0   360   120\n 3.8    0.3   0.6   0   360   120\n 1.7   -0.3   0.6   0   360   120\n 3.1   -0.3   0.6   0   360   120\nEOD\n\nX(n)  = real(word($myCircleParams[n],1))   # center x\nY(n)  = real(word($myCircleParams[n],2))   # center y\nR(n)  = real(word($myCircleParams[n],3))   # radius\nA0(n) = real(word($myCircleParams[n],4))   # start angle\nA1(n) = real(word($myCircleParams[n],5))   # end   angle\nN(n)  =  int(word($myCircleParams[n],6))   # number of samples\n\nset table FILE\n    do for [i=1:|$myCircleParams|] {\n        set samples N(i)\n        plot [A0(i):A1(i)] \'+\' u (X(i)+R(i)*cos($1)):(Y(i)+R(i)*sin($1))\n    }\nunset table\n\nset size ratio -1\nplot FILE u 1:2:-2 w l lc var\n### end of script\n
Run Code Online (Sandbox Code Playgroud)\n

奇怪的是,以前的版本适用于 gnuplot5.2.0 至 5.2.7,但不适用于 gnuplot>=5.2.8。对于当前的脚本,反之亦然,但我还没有找到原因。

\n

更新: \n终于找到了为什么它不能与 <=5.2.7 一起使用。显然,5.2.7 和 5.2.8 之间的缩放比例发生了变化。wxt或以外的其他终端qt可能具有不同的缩放系数。\n您需要添加/更改行(已在下面的脚本中添加):

\n
Factor = GPVAL_VERSION==5.2 && int(GPVAL_PATCHLEVEL)<=7 ? \\\n         GPVAL_TERM eq "wxt" ? 20 : GPVAL_TERM eq "qt" ? 10 : 1 : 1\nRxaupu = (GPVAL_X_MAX-xmin)/(GPVAL_TERM_XMAX-xtmin)*Factor   # x ratio axes units to pixel units\nRyaupu = (GPVAL_Y_MAX-ymin)/(GPVAL_TERM_YMAX-ytmin)*Factor   # y\n
Run Code Online (Sandbox Code Playgroud)\n

脚本:(使用 gnuplot 5.2.0、5.2.7、5.2.8、5.4.1 测试)

\n
### Add hatch pattern to a curve\nreset session\n\nFILE = "SO57118566.dat"\n\nset size ratio -1       # set same x,y scaling\nset angle degree\nunset key\n\n# plot path without hatch lines to get the proper gnuplot variables: GPVAL_...\nplot FILE u 1:2:-2 w l lc var\n\n# Hatch parameters:\n# TiltAngle     >0\xc2\xb0: left side, <0\xc2\xb0 right side in direction of path\n# HatchLength   hatch line length in pixels\n# HatchGap      separation of hatch lines in pixels\n# TA   HL   HG   Color\n$myHatchParams <<EOD\n -90   10    5   0x0080ff\n -30   15   10   0x000000\n  90    5    3   0xff0000\n  45   25   12   0xffff00\n -60   10    7   0x00c000\nEOD\n# extract hatch parameters\nTA(n)    = real(word($myHatchParams[n],1))   # TiltAngle\nHL(n)    = real(word($myHatchParams[n],2))   # HatchLength\nGpx(n)   = real(word($myHatchParams[n],3))   # HatchGap in pixels\nColor(n) =  int(word($myHatchParams[n],4))   # Color\n\n# terminal constants\nxmin   = GPVAL_X_MIN\nymin   = GPVAL_Y_MIN\nxtmin  = GPVAL_TERM_XMIN\nytmin  = GPVAL_TERM_YMIN\nFactor = GPVAL_VERSION==5.2 && int(GPVAL_PATCHLEVEL)<=7 ? \\\n         GPVAL_TERM eq "wxt" ? 20 : GPVAL_TERM eq "qt" ? 10 : 1 : 1\nRxaupu = (GPVAL_X_MAX-xmin)/(GPVAL_TERM_XMAX-xtmin)*Factor   # x ratio axes units to pixel units\nRyaupu = (GPVAL_Y_MAX-ymin)/(GPVAL_TERM_YMAX-ytmin)*Factor   # y\n\nAngle(dx,dy) = dx==0 && dy==0 ? NaN : atan2(dy,dx)    # -180\xc2\xb0 to +180\xc2\xb0, NaN if dx,dy==0\nLP(dx,dy)    = sqrt(dx**2 + dy**2)        # length of path segment\nax2px(x)     = (x-xmin)/Rxaupu  + xtmin   # x axes coordinates to pixel coordinates\nay2py(y)     = (y-ymin)/Rxaupu  + ytmin   # y\npx2ax(x)     = (x-xtmin)*Rxaupu + xmin    # x pixel coordinates to axes coordinates\npy2ay(y)     = (y-ytmin)*Rxaupu + ymin    # y\n\n# create datablock $Path with pixel coordinates and cumulated path length\nstats FILE u 0 nooutput    # get number of blocks of input file\nN = STATS_blocks\nset table $Path\n    do for [i=0:N-1] {\n        x1 = y1 = NaN\n        Length = 0\n        plot FILE u (x0=x1, x1=ax2px($1)):(y0=y1, y1=ay2py($2)): \\\n            (dx=x1-x0, dy=y1-y0, ($0>0?Length=Length+LP(dx,dy):Length)) index i w table\n        plot \'+\' u (\'\') every ::0::1 w table    # two empty lines\n    }\nunset table\n\n# create hatch lines table\n# resample data in equidistant steps along the length of the path\n$Temp <<EOD    # datablock $Temp definition required for function definition below\nEOD\nx0(n)    = real(word($Temp[n],1))                # x coordinate\ny0(n)    = real(word($Temp[n],2))                # y coordinate\nr0(n)    = real(word($Temp[n],3))                # cumulated path length \nap(n)    = Angle(x0(n+1)-x0(n),y0(n+1)-y0(n))    # path angle\nah(n,i)  = ap(n)+TA(i+1)                         # hatch line angle\nFrac(n)  = (ri-r0(n))/(r0(n+1)-r0(n))            # interpolation along\nhsx(n)   = (x0(n) + Frac(n)*(x0(n+1)-x0(n)))     # x hatch line start point\nhsy(n)   = (y0(n) + Frac(n)*(y0(n+1)-y0(n)))     # y\nhex(n,i) = (hsx(n) + HL(i+1)*cos(ah(n,i)))       # x hatch line end point\nhey(n,i) = (hsy(n) + HL(i+1)*sin(ah(n,i)))       # y\n\n# create datblock with hatchlines x,y,dx,dy\nset print $HatchLines\n    do for [i=0:N-1] {\n        set table $Temp\n            splot $Path u 1:2:3 index i\n        unset table\n\n        ri = -Gpx(i+1)\n        do for [j=1:|$Temp|-2] {\n            if (strlen($Temp[j])==0 || $Temp[j][1:1] eq \'#\') {print $Temp[j]}\n            else {\n                while (ri<r0(j)) {\n                    ri = ri + Gpx(i+1)\n                    print sprintf("%g %g %g %g", \\\n                    xs=px2ax(hsx(j)), ys=py2ay(hsy(j)), \\\n                    px2ax(hex(j,i))-xs, py2ay(hey(j,i))-ys)\n                }\n            }\n        }\n        print ""; print ""   # two empty lines\n    }\nset print\n\nplot $Path u (px2ax($1)):(py2ay($2)):(Color(column(-2)+1))  w l lc rgb var, \\\n     $HatchLines u 1:2:3:4:(Color(column(-2)+1)) w vec nohead lc rgb var\n### end of script\n
Run Code Online (Sandbox Code Playgroud)\n

结果:

\n

在此输入图像描述

\n