如何在gnuplot中获取曲线上指定x坐标对应的y值
在Gnuplot中获取曲线上指定X坐标对应的Y值
下面介绍几种实用方法,覆盖不同使用场景:
方法1:生成插值数据集后提取(快速验证场景)
如果你的曲线是基于原始数据插值绘制的(比如用with lines或smooth选项),可以先把插值后的所有点导出到临时文件,再提取目标X对应的Y值:
# 生成插值后的完整数据点到临时文件(使用你绘图时的插值方式,比如csplines或默认线性) set table 'temp_interp.dat' plot 'your_data_file.txt' with lines smooth csplines unset table # 提取指定X值对应的Y(以X=2.5为例,Unix环境可直接用shell命令) print `awk -v x=2.5 'BEGIN{min_diff=9999} {diff=sqrt(($1-x)^2); if(diff<min_diff){min_diff=diff; y=$2}} END{print y}' temp_interp.dat`
临时文件temp_interp.dat包含所有插值后的(X,Y)点,上述awk命令会找到最接近目标X的点并输出其Y值。
方法2:纯Gnuplot内置插值计算(跨平台无依赖)
适合需要在脚本中直接计算、不想依赖外部工具的场景,以线性插值为例:
# 1. 把数据读入数组(假设数据文件是data.txt,第一列X,第二列Y) array x_vals[1000] array y_vals[1000] record_count = 0 stats 'data.txt' using (record_count=record_count+1, x_vals[record_count]=$1, y_vals[record_count]=$2) nooutput # 2. 定义线性插值函数 linear_interpolate(x_target) = ( \ idx = 1; \ while (idx < record_count && x_vals[idx] < x_target) {idx = idx + 1}; \ if (idx == 1) y_vals[1]; \ else if (idx > record_count) y_vals[record_count]; \ else y_vals[idx-1] + (y_vals[idx] - y_vals[idx-1])*(x_target - x_vals[idx-1])/(x_vals[idx] - x_vals[idx-1]) \ ) # 3. 计算并输出目标X对应的Y值(比如X=3.0) print linear_interpolate(3.0)
如果需要样条插值,可替换为Gnuplot的cspline拟合功能:
# 样条插值示例 set fit spline fit cspline(x) 'data.txt' using 1:2 via a,b,c,d print cspline(3.0)
方法3:绘图时直接输出目标点
如果需要在绘图同时获取该值,可在plot命令中加入计算逻辑:
# 先定义插值函数(同方法2) array x_vals[1000] array y_vals[1000] record_count = 0 stats 'data.txt' using (record_count=record_count+1, x_vals[record_count]=$1, y_vals[record_count]=$2) nooutput linear_interpolate(x_target) = ( \ idx = 1; \ while (idx < record_count && x_vals[idx] < x_target) {idx = idx + 1}; \ if (idx == 1) y_vals[1]; \ else if (idx > record_count) y_vals[record_count]; \ else y_vals[idx-1] + (y_vals[idx] - y_vals[idx-1])*(x_target - x_vals[idx-1])/(x_vals[idx] - x_vals[idx-1]) \ ) # 绘图同时输出目标X的Y值 x_target = 3.0 plot 'data.txt' with lines, \ x_target linear_interpolate(x_target) with points pt 7 title sprintf("X=%.1f, Y=%.3f", x_target, linear_interpolate(x_target)), \ print sprintf("X=%.1f对应的Y值:%.3f", x_target, linear_interpolate(x_target))
执行后终端会输出目标值,同时图上会标记出该点。
内容的提问来源于stack exchange,提问作者AAA
相关产品推荐
相关产品推荐

