如何使用gnuplot以输入文件中的数据给定的一定偏移量绘制平行于x轴的线

如何使用gnuplot以输入文件中的数据给定的一定偏移量绘制平行于x轴的线,gnuplot,Gnuplot,我在一个漂亮的小Fortran程序中,用傅里叶网格哈密顿方法计算了一维氢原子在原子单位中的哈密顿量的本征值 在-1和0(束缚态)之间找到的所有特征值都会逐行保存到文件中,如下所示: -0.50016671392950229 -0.18026105614262633 -0.11485673263086937 -4.7309305955423042E-002 -4.7077108902158216E-002 由于找到的特征值的数量取决于我的程序使用的步长,因此文件中的条目数量可能会有所不同(理论上

我在一个漂亮的小Fortran程序中,用傅里叶网格哈密顿方法计算了一维氢原子在原子单位中的哈密顿量的本征值

在-1和0(束缚态)之间找到的所有特征值都会逐行保存到文件中,如下所示:

-0.50016671392950229
-0.18026105614262633
-0.11485673263086937
-4.7309305955423042E-002
-4.7077108902158216E-002
由于找到的特征值的数量取决于我的程序使用的步长,因此文件中的条目数量可能会有所不同(理论上,有无限个条目)

现在,我想将文件中的值绘制为一条平行于x轴的线,偏移量由从文件中读取的值给定。 我还希望能够将数据绘制到一个特定的行号,因为数值越接近于零,它们就无法用肉眼区分

(例如,这里有必要绘制前四个条目,第五个条目与前一个条目已经太接近了)

我知道可以使用命令
plot*offset*
绘制平行于x轴的线,但我不知道如何告诉gnuplot使用文件中的数据。到目前为止,我不得不手动绘制这些值

作为第二步,我想只在特定的x范围内绘制数据,在与数值解所用谐波电势相交的点之间绘制更具体的曲线
V(x)=-1/(1+abs(x))

结果应该如下所示:

我最接近的,是和

plot -1/(1+abs(x)),-0.5 title 'E0',-0.18 title 'E1', -0.11 title 'E2'
这让我得到了以下结果:


希望你们能帮助我,我真的很好奇gnuplot是否真的能完成我描述的第二步

对于问题的第一部分,例如,您可以使用
xerrorbars
打印样式:

set terminal pngcairo
set output 'fig.png'

unset key
set xr [-1:1]
set yr [-1:0]

unset bars
plot '-' u (0):($1<-0.1?$1:1/0):(1) w xerrorbars pt 0 lc rgb 'red'
-0.50016671392950229
-0.18026105614262633
-0.11485673263086937
-4.7309305955423042E-002
-4.7077108902158216E-002
e
产生


这个想法基本上和以前一样,只是误差条的宽度现在取决于y坐标(能量)。此外,使用
标签
样式可以生成明确的标签。

另一种方法可能是使用
系统
cat
命令(假设是一个类似于x的系统…)从“energy.dat”(如问题中所示)获取数据,并通过
max在每个x处选择V(x)和E:

set key bottom right
set yr [-1:0.2]
set samples 1000

Edat = system( "cat energy.dat" )

max(a,b) = ( a > b ) ? a : b
V(x) = -1/(1+abs(x))

plot for [ E in Edat ] \
     max(V(x),real(E)) title sprintf("E = %8.6f", real(E)) lw 2, \
     V(x) title "V(x) = -1/(1+|x|)" lc rgb "red" lw 2

如果我们将电势改为
V(x)=-abs(cos(x))
,图看起来很有趣(能级当然不正确!)


有关脚本的更多详细信息:

  • max
    不是Gnuplot中的内置函数,而是具有两个形式参数的用户定义函数。例如,我们可以将其定义为

    mymax(p,q)=(p>q)?p:q

使用任何其他名称(并在
plot
命令中使用
mymax
)。接下来,
符号是一个符号,它为
if
else
构造提供了一个简写符号。在伪代码中,它作为

function max( a, b ) {
    if ( a > b ) then
        return a
    else
        return b
    end
}
这样,
max(V(x),real(E))
为任何给定的
x
E
选择
V(x)
real(E)
之间的较大值

  • 接下来,
    Edat=system(“cat energy.dat”)
    告诉Gnuplot运行shell命令“cat energy.dat”,并将输出分配给新变量
    Edat
    。在上述情况下,
    Edat
    成为一个字符串,其中包含从“energy.dat”读取的一系列能量值。您可以通过
    print(Edat)
    检查
    Edat
    的内容。例如,它可能类似于

    Edat=“-0.11-0.22…-0.5002”

  • Edat中[E]的绘图…
    在字符串
    Edat
    中包含的单词上循环。在上述情况下,
    E
    逐个获取字符串“-0.11”、“-0.22”、…、“-0.5002”
    real(E)
    将此字符串转换为浮点值。它用于将
    E
    (字符串)传递给任何数学函数

  • 基本思想是在E的每个值上绘制一个截断电位,最大值(V(x),E)(例如,您可以通过
    绘制最大值(V(x),-0.5)
    来检查这种电位的形状)。绘制此类曲线后,我们重新绘制电位
    V(x)
    ,使其显示为具有不同颜色的单个电位曲线

  • set samples 1000
    使用每条曲线1000个点增加绘图分辨率。1000是任意的,但这似乎足以使图形非常平滑


看起来相当不错!为了了解我自己,你在这里做了什么,如果你能解释一下
max(a,b)=(a>b)就好了?a:b
对我来说更详细的部分,我既没有找到一个很好的教程来解释这个关键词,也不理解它为什么要这么做;)谢谢你的漂亮解决方案!嗨,我已经添加了一些关于脚本的附加信息。因为我使用Gnuplot是非常经验性的,所以我的解释在各个部分可能不是很好或准确,所以请参考其他页面以获得更多信息。(仅供参考,我以前也使用过傅里叶网格哈密顿量,非常有用:)
function max( a, b ) {
    if ( a > b ) then
        return a
    else
        return b
    end
}