gnuplot中的逐步函数

gnuplot中的逐步函数,gnuplot,Gnuplot,我想知道如何在Gnuplot中创建逐步函数的绘图。我想要绘制的函数包括多个距离范围和多个产品的操作成本。例如,如果产品1的距离为0-300公里,则成本为1.05美元/公里,而产品2的成本为0.86美元/公里。当距离增加时,每种产品的成本降低 我为每个产品定义了一个函数,并将它们的函数绘制在一起: gnuplot> f(x)=x<=300 ? 1.05 : x<=650 ? 0.65 : x<=1300 ? 0.46 : x<=1950 ? 0.4 : x<=3

我想知道如何在Gnuplot中创建逐步函数的绘图。我想要绘制的函数包括多个距离范围和多个产品的操作成本。例如,如果产品1的距离为0-300公里,则成本为1.05美元/公里,而产品2的成本为0.86美元/公里。当距离增加时,每种产品的成本降低

我为每个产品定义了一个函数,并将它们的函数绘制在一起:

gnuplot> f(x)=x<=300 ? 1.05 : x<=650 ? 0.65 : x<=1300 ? 0.46 : x<=1950 ? 0.4 : x<=3250 ? 0.31 : 0.22

gnuplot> x<=300 ? 0.86 : x<=650 ? 0.53 : x<=1300 ? 0.38: x<=1950 ? 0.32 : x<=3250 ? 0.24 : 0.19

gnuplot> plot [0:5000][0:3] f(x), g(x)

gnuplot>f(x)=x基本上可以采取两种方法。最好的方法是使用数据文件,但您可以使用函数,尽管这将更加困难

数据文件方法 作为一个函数,你可能会遇到麻烦,因为你会得到那些垂直线。数据文件为您提供了更好的控制,甚至允许您使用典型的开/闭点标记分段函数的端点。使用以下格式设置数据文件:

x y # left point of piece 1
x y # right point of piece 1
    # one single blank line
x y # left point of piece 2
x y # right point of piece 2
    # one single blank line
...
用函数f,我们可以这样做

0 1.05
300 1.05

300 0.65
650 0.65

650 0.46
1300 0.46

1300 0.4
1950 0.4

1950 0.31
3250 0.31

3250 0.22
6000 0.22
然后
用线绘制数据文件
给出

使用

产生

这里我们首先绘制与之前相同的曲线。然后我们将变量last初始化为0(第一个x坐标的值),并绘制开放点

为此,我们计算
(oldlast=last,last=$1,$1==oldlast?$2:1/0)
,它首先将last的值存储为oldlast,然后将第一列(x坐标)的值存储为下一点上使用的最后一列。最后,我们检查x坐标是否与oldlast的值(从最后一点开始的x坐标值)相同。如果是,则使用第二列值,否则使用不可打印的
1/0
。这将导致仅当点是两个点块中的第一个点时才打印点。我们使用pointstyle 6(开放点)和线型1(与直线中使用的相同)绘制这些点

我们再次做同样的事情,但这次用填充点绘制第二个点(点类型7)

我们可以将函数g的点添加到同一个文件中,用两个空行将其与其他文件分开,然后使用索引引用它们,或者为g创建一个单独的数据文件。然后,我们可以将类似的绘图命令添加到当前命令。例如,如果将同一个文件与函数f和函数g一起使用,则可以执行以下操作:

plot datafile i 0 w lines,\
     last=0,\
     "" i 0 u 1:(oldlast=last,last=$1,$1==oldlast?$2:1/0) w points pt 6 lt 1,\
     last=0,\         
     "" i 0 u 1:(oldlast=last,last=$1,$1==oldlast?1/0:$2) w points pt 7 lt 1,\
     datafile i 1 w lines,\
     last=0,\
     "" i 1 u 1:(oldlast=last,last=$1,$1==oldlast?$2:1/0) w points pt 6 lt 1,\
     last=0,\         
     "" i 1 u 1:(oldlast=last,last=$1,$1==oldlast?1/0:$2) w points pt 7 lt 1
函数法 至于只获得一次跳转,您的函数有很多冗余条件。将f(与g类似)重新定义为

我们得到

但是,这仍然会得到垂直连接线。这对于函数来说是很难避免的。我能想到的避免这种情况的最好方法是在中断之前注入一个非常小的不可绘制的值。对于f(x),我们可以用

f(x)=x<=290 ? 1.05 : x<=300? (1/0) : x<=640? 0.65 : x<=650 ? (1/0) : x<=1290 ? 0.46 : x<=1300 ? (1/0) : x<=1940? 0.4 : x<=1950 ? (1/0) : x<=3240 ? 0.31: x<=3250? (1/0) : 0.22
抽样10次,我们得到

如果间隙的大小为222.22(我添加了标签以便于计算间隙大小Δ),但如果采样为1000,我们得到

其中间隙的大小为101.1,非常接近函数中指定的值100

因此,要使用函数实现这一点,请使用此模型并将间隙大小设置为足够小的值,使其在最终图形上看起来不存在(请注意,在0到6000的图形上,我们几乎看不到间隙大小10),然后将样本设置得相当高

对于函数方法,如果需要,我不知道如何添加填充点和开放点


Gnuplot版本5.1(当前开发版本)支持
pointtype变量
选项,该选项可简化为

plot last=0,\
     datafile u 1:2:(oldlast=last,last=$1,$1==oldlast?6:7) w linespoints pt var lt 1
这里我们只绘制所有点,但使用与之前相同的测试在点类型7或6之间进行选择。因为我们可以同时进行两种点类型的绘制,所以我们可以使用linespoints样式,而不是进行两个单独的打印

——将最后一个初始化为小于第一个x坐标的值将导致第一个点被填充

Δ为了绘制这些标签,在第一种情况下(使用
设置xrange[0:1000]
设置样本10
),我使用


只需稍微调整一下
abs
函数的边界,即可获得所需的标签。使用
set table
检查输出有助于正确处理它们。

您的三元语句试图做得太多了。当你写作的时候

f0(x)=(x_low < x <= x_high) ? y : 0

对于打印样式,如果希望其不连续,请对步骤(如)使用单独的函数,并单独打印它们。您的第一个函数将被拆分为:

f1(x)=           (x<=300) ? 1.05 : 1/0
f2(x)=(x>300) && (x<=650) ? 0.65 : 1/0
...

似乎我不允许在我的帖子中添加图片。我希望我的问题在没有图像的情况下仍然足够清晰。我为您添加了图像。它与数据文件配合得非常好。谢谢一个简单的问题:有没有办法指定我保存数据文件的文件夹的路径,一次他们只是通过名称(如stepwise.txt)而不是整个路径引用数据文件?@Helia您可以将文件路径存储在一个变量中,然后使用该变量而不是指定文件路径。例如
datafile=“path/to/file.txt”
(或在Windows上
datafile=“c:\\path\\to\\file.txt”
),然后在绘图命令中使用变量datafile,如
plot datafile u 1:2
。我现在唯一的问题是打印多个数据文件(每个产品一个)。新步骤的某些行,开始位置非常靠近属于上一步骤的行的末尾。它们甚至在某些点上重叠。@Helia不知道您的数据是什么样子,也不知道您正在运行的命令,对此我不能说太多。如果它们接近相同的值,则它们应该开始接近相同的行。如果它们具有相同的值,则它们将
f(x)=x<=200 ? 1.05 : x<=300? (1/0) : x<=550? 0.65 : x<=650 ? (1/0) : x<=1200 ? 0.46 : x<=1300 ? (1/0) : x<=1850? 0.4 : x<=1950 ? (1/0) : x<=3150 ? 0.31: x<=3250? (1/0) : 0.22
plot last=0,\
     datafile u 1:2:(oldlast=last,last=$1,$1==oldlast?6:7) w linespoints pt var lt 1
plot f(x),\
     "+" u 1:(f($1)+0.1):(abs($1-250)<150||abs($1-600)<160?sprintf("%0.2f",$1):"") w labels
plot f(x),\
     "+" u 1:(f($1)+0.1):(abs($1-250)<51||abs($1-600)<51?sprintf("%0.2f",$1):"") w labels
f0(x)=(x_low < x <= x_high) ? y : 0
f0(x)=((x_low < x) && ( x <= x_high)) ? y : 0
f(x)=(x<=300) ? 1.05 : (x<=650) ? 0.65 : (x<=1300) ? 0.46 : (x<=1950) ? 0.4 : (x<=3250) ? 0.31 : (x<3250) ? 0.22 : 0
f1(x)=           (x<=300) ? 1.05 : 1/0
f2(x)=(x>300) && (x<=650) ? 0.65 : 1/0
...
plot [0:6000][0:3] f(x) w steps, g(x) w steps