如何用仅含x与b(x)的数据文件绘制f(x,y)=y³*b(x)的等高线?
解决Gnuplot中绘制f(x,y)=y³*b(x)等高线的问题
我明白你遇到的困扰:手里只有x和b(x)的一维数据,但要画的是依赖x和y的二元函数等高线,原脚本里的splot写法没法正确关联x、y和z值。下面给你一步步梳理修正方案:
核心问题拆解
你的数据只有x和b(x),但目标函数f(x,y)是二元函数——gnuplot需要先把离散的b(x)数据转换成可对任意x调用的连续插值函数,再结合y的范围计算每个(x,y)对应的z值,而不是在using语句里临时赋值(这种写法只能处理当前行的x,无法覆盖整个xrange)。
修正后的完整可运行脚本
下面是直接可用的脚本,我会在后面解释关键部分:
reset # 1. 先把离散的b(x)数据插值成连续函数 set samples 1000 # 采样点越多,插值精度越高 set table 'b_interp.dat' plot 'Data.dat' u 1:2 with csplines # 用三次样条插值生成连续的b(x)数据 unset table # 2. 定义b_val(x):从插值后的数据中获取任意x对应的b(x)值 stats 'b_interp.dat' u 1:2 nooutput array b_data[STATS_records] do for [i=1:STATS_records] { set table $temp plot 'b_interp.dat' every ::i-1::i-1 u 1:2 with table unset table b_data[i][1] = $temp[1][1] b_data[i][2] = $temp[1][2] } # 线性插值获取任意x对应的b值,超出原数据范围时用边界值填充 b_val(x) = (sum [i=1:|b_data|-1] (x >= b_data[i][1] && x <= b_data[i+1][1]) ? \ b_data[i][2] + (b_data[i+1][2]-b_data[i][2])*(x - b_data[i][1])/(b_data[i+1][1]-b_data[i][1]) : \ (x < b_data[1][1] ? b_data[1][2] : b_data[|b_data|][2])) # 3. 定义目标二元函数 f(x,y) = y**3 * b_val(x) # 4. 生成image绘图用的test.dat(遍历x和y范围计算z值) set xrange [-6:6] set yrange [-5:5] set isosamples 100,100 # x/y方向采样数,按需调整精度 set table 'test.dat' splot x,y,f(x,y) # 直接遍历xrange/yrange,计算每个(x,y)对应的z unset table # 5. 生成等高线数据contour.dat set contour base set cntrparam bspline set cntrparam levels incremental -0.1,0.02,0.1 unset surface set table 'contour.dat' splot x,y,f(x,y) unset table # 6. 绘制最终图像 reset set xrange [-6:6] set yrange [-5:5] unset key set palette rgbformulae 33,13,10 plot 'test.dat' with image, 'contour.dat' w l lt -1 lw 1.5
原脚本的问题说明
你之前写的splot 'Data.dat' u 1:(b(x)=$2, f(x,y))有两个致命问题:
b(x)=$2只是把当前行的b值临时赋值,这个值不会随x的变化而更新,无法覆盖整个xrange的x值;- 数据文件里没有y列,gnuplot不知道要遍历y的范围,自然无法生成二元函数的z值矩阵。
额外小提示
- 如果你的
Data.dat已经覆盖了[-6:6]的x范围,可以适当减少set samples的数值来加快插值速度; set isosamples的数值决定了图像的精细度,数值越大图像越平滑,但生成文件的时间也会更长。
内容的提问来源于stack exchange,提问作者G.Ub




