我正在使用gnuplot绘制多个函数的轮廓图。这是为了优化问题。我有3个功能:
f(x,y) g1(x,y)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示例中复制教科书图片。如何在函数g1和g2上绘制阴影线,如上图所示。
@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)
这是您(和我)所希望的解决方案。\n您只需将填充参数输入数据块:TiltAngle以度为单位(>0\xc2\xb0:左侧,<0\xc2\xb0 路径方向右侧) ,HatchLength并HatchGap以像素为单位。该过程变得有点冗长,但它满足了您的要求。wxt我已经使用 gnuplot 5.2.8 和 5.4.1以及终端对其进行了测试qt。
该过程的基本作用是:
\nHatchSeparationGPVAL_X_MAX, GPVAL_X_MIN, GPVAL_TERM_XMAX, GPVAL_TERM_XMIN, GPVAL_Y_MAX, GPVAL_Y_MIN, GPVAL_TERM_YMAX, GPVAL_TERM_YMIN.限制:
\n编辑:( 完全修订版)
\n之前的脚本(在我看来)相当混乱且难以遵循(尽管没有人抱怨;-)。我删除了对子过程的调用,从而删除了子过程中变量的前缀,并将所有内容放入一个脚本中,测试数据生成除外。
\n享受孵化线条的乐趣!欢迎提出意见和改进!
\n测试数据生成: SO57118566_createTestData.gp
### 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\nRun 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您需要添加/更改行(已在下面的脚本中添加):
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\nRun 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\nRun Code Online (Sandbox Code Playgroud)\n结果:
\n\n