如何在 gnuplot 中使用不同的点类型划线?

发布于 2025-01-10 15:43:54 字数 1604 浏览 0 评论 0原文

我正在尝试用虚线绘制数据文件。以下是一些值:

2001 dic 21 5,9 9,2 3,8 0,2
2001 dic 22 6,8 8,7 4,8 4,2
2001 dic 23 6,3 8,1 6,5 6,8
2001 dic 24 3,1 4,1 3
2001 dic 25 -1, 3,5 -5
2001 dic 26 4,5 8 0,8 14,8
2001 dic 27 4 7 2,7 0,2
2001 dic 28 0,1 3,4 -3,5
2001 dic 29 7 10,7 2,9 6,2
2001 dic 30 11,2 12,9 8 1,4
2001 dic 31 5,2 6,3 5 3,4
2002 gen 1 2,9 6,9 0,8 
2002 gen 2 -0,8 5,4 -5,4 
2002 gen 3 2,0 8,0 -1,8 
2002 gen 4 2,0 5,2 0,1 
2002 gen 5 -0,8 5,5 -5,2 
2002 gen 6 0,3 6,7 -4,3 
2002 gen 7 0,5 5,6 -3,4 
2002 gen 8 1,2 7,9 -3,3 
2002 gen 9 1,9 8,4 -2,8 
2002 gen 10 1,8 8,1 -2,7 
2002 gen 11 3,6 7,7 -0,7 
2002 gen 12 6,0 10,2 3,5 

为了避免与其他图表混淆,我应该绘制的不是精确的虚线而是珠子(“°”)。 Gnuplot 只允许使用“.-_”来表示用户定义的虚线。使用用户定义的线点进行绘图可能是解决方案,但是您有线条和珠子,而不仅仅是“珠子”,如下所示(查看中间的图): 3 graphplot

仅使用 user- 进行绘图定义点珠子之间留下很多空白空间。因此,我尝试创建一个新的数据文件,其中包含通过原始数据文件值的线性插值获得的更多值,以填充这些空白空间(前三列是“2022 年 2 月 28 日”等类型的时间戳数据):

set table $Temp
     plot "datafile.csv" u 1:4:5:6:7 skip 15 w table 
unset table

set print $Temp2  #this file is like $Temp with lots of values added by interpolation   
  do for [i = 1:|$Temp|-1] { 
  print $Temp[i:($1)],$Temp[i:($4)]
              do for [j = 1,10] { print $Temp[i:($1)]+($Temp[i+1:($1)]-$Temp[i:($1)])*j/11), $Temp[i:($4)]+($Temp[i+1:($4)]-$Temp[i:($4)])*j/11) }
              } 
  print $Temp[|$Temp|:($1)],$Temp[|$Temp|:($4)]  
    set print

显然这不起作用,因为我没有正确处理 $Temp 文件的列。在 gnuplot 手册中查找“数组”没有提供任何提示。最后,生成的文件应该用点 pt“°”绘制。

I'm trying to plot a datafile with dashed lines. Here are some of the values:

2001 dic 21 5,9 9,2 3,8 0,2
2001 dic 22 6,8 8,7 4,8 4,2
2001 dic 23 6,3 8,1 6,5 6,8
2001 dic 24 3,1 4,1 3
2001 dic 25 -1, 3,5 -5
2001 dic 26 4,5 8 0,8 14,8
2001 dic 27 4 7 2,7 0,2
2001 dic 28 0,1 3,4 -3,5
2001 dic 29 7 10,7 2,9 6,2
2001 dic 30 11,2 12,9 8 1,4
2001 dic 31 5,2 6,3 5 3,4
2002 gen 1 2,9 6,9 0,8 
2002 gen 2 -0,8 5,4 -5,4 
2002 gen 3 2,0 8,0 -1,8 
2002 gen 4 2,0 5,2 0,1 
2002 gen 5 -0,8 5,5 -5,2 
2002 gen 6 0,3 6,7 -4,3 
2002 gen 7 0,5 5,6 -3,4 
2002 gen 8 1,2 7,9 -3,3 
2002 gen 9 1,9 8,4 -2,8 
2002 gen 10 1,8 8,1 -2,7 
2002 gen 11 3,6 7,7 -0,7 
2002 gen 12 6,0 10,2 3,5 

For avoiding confusion with other graphs, I should plot not exactly dashed lines but beads ('°'). Gnuplot permits only ".-_" for user-defined dashed lines. Plotting with user-defined linespoints could be the solution but there you have lines and beads, not just 'beads', something like this (look at the plot in the middle): 3 graph plot

To plot with just user-defined points leaves a lot of empty spaces between the beads. So I'm trying to create a new datafile with many more values obtained by linear interpolation of the primitive datafile values, to fill those empty spaces (the first three columns are timestamp data of the kind '2022 feb 28' and the like):

set table $Temp
     plot "datafile.csv" u 1:4:5:6:7 skip 15 w table 
unset table

set print $Temp2  #this file is like $Temp with lots of values added by interpolation   
  do for [i = 1:|$Temp|-1] { 
  print $Temp[i:($1)],$Temp[i:($4)]
              do for [j = 1,10] { print $Temp[i:($1)]+($Temp[i+1:($1)]-$Temp[i:($1)])*j/11), $Temp[i:($4)]+($Temp[i+1:($4)]-$Temp[i:($4)])*j/11) }
              } 
  print $Temp[|$Temp|:($1)],$Temp[|$Temp|:($4)]  
    set print

Obviously this does not work since I'm not handling the columns of the $Temp file correctly. Looking up "arrays" in gnuplot manual does not provide any hint. At the end, the resulting file should be plotted with points pt "°".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不忘初心 2025-01-17 15:43:54

编辑:由于我将问题标题更改为“...不同点类型...”,我应该展示如何使用多列和不同的点类型来完成此操作。
多列的数据沿着路径插入,并作为(子)块附加到数据块 $DashMultipleCols 中,稍后可以通过 index 对其进行寻址。我让你来决定是实线/虚线/点线还是加号/圆形/三角形更容易区分。

以下示例创建一个沿给定路径具有等距点的数据块。

  • 为了说明,一些随机测试数据是使用 1 个 x 列和 3 个 y 列创建的

  • 为了进行比较,第一个图表包含实线、虚线和点线。在我看来,这些线条可以很好地区分,但你要求用符号“划线”。

  • 对于第二个图,第 2、3、4 列的数据分别用点类型 1、6、8 进行“虚线”显示。

  • 符号之间的距离由变量设置,此处:Dist = 8

  • 为了获得视觉上均匀的分布,使用从 x,y 到像素坐标的坐标转换以及反向转换。为此,使用 gnuplot 变量 GPVAL...,这些变量在绘图后可用。这就是为什么有必要绘制两次。可以删除命令pause -1

  • 这适用于线性轴(需要调整对数轴)

  • 您的数据是时间数据。代码需要做相应的调整。

代码:(使用wxt终端测试)

### "dashing" with symbols equidistantly along a path
reset session

# create some random test data
set print $Data
    x0 = 0
    y0 = y1 = y2 = 100
    do for [i=1:10] {
        print sprintf("%g %g %g %g", x0=x0+int(rand(0)*10)+5, y0=y0+int(rand(0)*10)-5, y1=y1+int(rand(0)*10)-5, y2=y2+int(rand(0)*10)-5)
    }
set print

set key top left Left reverse
# plot to get the GPVAL_ ... values
plot $Data u 1:2 w l dt 1 lc "black" ti "Column 2, solid", \
        '' u 1:3 w l dt 2 lc "black" ti "Column 3, dashed", \
        '' u 1:4 w l dt 3 lc "black" ti "Column 4, dotted"

# store GPVAL parameters after plot in variables
txmin = GPVAL_TERM_XMIN
txmax = GPVAL_TERM_XMAX
tymin = GPVAL_TERM_YMIN
tymax = GPVAL_TERM_YMAX
xmin  = GPVAL_X_MIN
xmax  = GPVAL_X_MAX
ymin  = GPVAL_Y_MIN
ymax  = GPVAL_Y_MAX

# x,y to pix and pix to x,y coordinate conversion
XtoPix(x)    = txmin + real(x-xmin)    *(txmax-txmin)/( xmax- xmin)
YtoPix(y)    = tymin + real(y-ymin)    *(tymax-tymin)/( ymax- ymin)
PixToX(scrx) =  xmin + real(scrx-txmin)*( xmax- xmin)/(txmax-txmin)
PixToY(scry) =  ymin + real(scry-tymin)*( ymax- ymin)/(tymax-tymin)

# get lengths and angles in pixel coordinates
set angle degrees
Length(x0,y0,x1,y1) = sqrt((x1-x0)**2 + (y1-y0)**2)
Angle(x0,y0,x1,y1)  = (_dx=x1-x0, _dy=y1-y0, _L=sqrt(_dx**2 + _dy**2), _L==0 ? NaN : \
                      (_dy>=0 ? acos(_dx/_L) : 360-acos(_dx/_L) ))

colX  = 1
colsY = "2 3 4"         # multiple y-columns
do for [colY in colsY] {
    set table $LaA      # table for length and angles
        Total = 0
        plot x1=y1=NaN $Data u (x0=x1,x1=XtoPix(column(colX)),x0):\
                               (y0=y1,y1=YtoPix(column(int(colY))),y0):\
                (L=Length(x0,y0,x1,y1)):(L==L ? Total=Total+L : 0, Angle(x0,y0,x1,y1)) w table
    unset table
    X0(n)        = real(word($LaA[n],1))
    Y0(n)        = real(word($LaA[n],2))
    SegLength(n) = real(word($LaA[n],3))
    SegAngle(n)  = real(word($LaA[n],4))

    # create equidistant datapoints along path
    set print $DashSingleCol
        Dist = 8                    # Distance between symbols
        N = floor(Total/Dist)
        idx = 2
        L0 = 0
        L = SegLength(idx)
        do for [i=0:N] {
            R = i*Dist
            while (L-R<0) {
                L0 = L
                idx = idx + 1
                L = L + SegLength(idx)
            }
            print sprintf("%g %g", PixToX(X0(idx)+(R-L0)*cos(SegAngle(idx))), \
                                   PixToY(Y0(idx)+(R-L0)*sin(SegAngle(idx))))
        }
    set print
    set print $DashMultipleCols append
        print $DashSingleCol
        print "\n\n"
    set print
}

pause -1 

mySymbol(n) = int(word("1 6 8",n))

plot for [i=1:words(colsY)] $DashMultipleCols u 1:2:(mySymbol(i)) index i-1 \
          w p pt mySymbol(i) ps 0.6 lc "black" ti sprintf("Column %s, Symbol %d",word(colsY,i),mySymbol(i))
### end of code

结果:

在此处输入图像描述

在此处输入图像描述

添加: 适合时间格式的

代码gnuplot 中的时间只不过是自 1970 年 1 月 1 日 00:00:00 以来经过的秒数。如果您在 gnuplot 控制台中输入 print time(0) (即当前时间),您将得到类似 1646757721 的信息,因此从那时到今天已经过去了大约 16 亿秒。

与上面的代码相比,主要区别和需要记住的事情:

  • 定义您的特定时间格式,例如 myTimeFmt = "%Y %b %d"
  • 使用此时间格式和中间的空格,您的数据将位于第 4,5 和 6 列中。
  • 用于首次使用时绘制数据,例如 plot $Data u (timecolumn(1,myTimeFmt)):4 w l
  • 用于长度和角度表($LaA) 您还必须使用第 4,5,6 列和 timecolumn(),即 plot x1=y1=NaN $Data u ( x0=x1,x1=XtoPix(timecolumn(colX,myTimeFmt)),x0)
  • 用于创建数据块 $DashSingleCol 您必须强制使用格式时间为 "%.0f"print sprintf("%.0f %g", PixToX(X0(idx)+(R-L0)*cos(SegAngle(idx) ))) 否则,使用 "%g" gnuplot 会写出一个带有指数但只有 6 位数字的浮点数,例如1.64676e+09 这对于绘制 $DashMultipleCols 来说是不需要的截断或舍入,
  • 您可以简单地使用 u 1:2 因为时间已经到了。以秒为单位,并且不必通过 timecolumn() 进行更改。

我希望这些额外的代码和解释将帮助您用不同的符号“破折号”您的数据。

代码:

### "dashing" with symbols equidistantly along a path (with timedata)
reset session

myTimeFmt = "%Y %b %d"

# create some random test data
set print $Data
    t0 = time(0)
    y0 = y1 = y2 = 10
    SecsPerDay =  24*3600   # seconds per day
    do for [i=1:10] {
        t0=t0+int(rand(0)*10*SecsPerDay)+5*SecsPerDay
        print sprintf("%s %g %g %g", strftime(myTimeFmt,t0), \
                y0=y0+int(rand(0)*10)-5, y1=y1+int(rand(0)*10)-5, y2=y2+int(rand(0)*10)-5)
    }
set print

set key top left Left reverse
# plot to get the GPVAL_ ... values
set format x "%b %01d\n%Y" timedate
plot $Data u (timecolumn(1,myTimeFmt)):4 w l dt 1 lc "black" ti "Column 4, solid", \
        '' u (timecolumn(1,myTimeFmt)):5 w l dt 2 lc "black" ti "Column 5, dashed", \
        '' u (timecolumn(1,myTimeFmt)):6 w l dt 3 lc "black" ti "Column 6, dotted"

# store GPVAL parameters after plot in variables
txmin = GPVAL_TERM_XMIN
txmax = GPVAL_TERM_XMAX
tymin = GPVAL_TERM_YMIN
tymax = GPVAL_TERM_YMAX
xmin  = GPVAL_X_MIN
xmax  = GPVAL_X_MAX
ymin  = GPVAL_Y_MIN
ymax  = GPVAL_Y_MAX

# x,y to pix and pix to x,y coordinate conversion
XtoPix(x)    = txmin + real(x-xmin)    *(txmax-txmin)/( xmax- xmin)
YtoPix(y)    = tymin + real(y-ymin)    *(tymax-tymin)/( ymax- ymin)
PixToX(scrx) =  xmin + real(scrx-txmin)*( xmax- xmin)/(txmax-txmin)
PixToY(scry) =  ymin + real(scry-tymin)*( ymax- ymin)/(tymax-tymin)

# get lengths and angles in pixel coordinates
set angle degrees
Length(x0,y0,x1,y1) = sqrt((x1-x0)**2 + (y1-y0)**2)
Angle(x0,y0,x1,y1)  = (_dx=x1-x0, _dy=y1-y0, _L=sqrt(_dx**2 + _dy**2), _L==0 ? NaN : \
                      (_dy>=0 ? acos(_dx/_L) : 360-acos(_dx/_L) ))

colX  = 1
colsY = "4 5 6"         # multiple y-columns
do for [colY in colsY] {
    set table $LaA      # table for length and angles
        Total = 0
        plot x1=y1=NaN $Data u (x0=x1,x1=XtoPix(timecolumn(colX,myTimeFmt)),x0):\
                               (y0=y1,y1=YtoPix(column(int(colY))),y0):\
                (L=Length(x0,y0,x1,y1)):(L==L ? Total=Total+L : 0, Angle(x0,y0,x1,y1)) w table
    unset table
    X0(n)        = real(word($LaA[n],1))
    Y0(n)        = real(word($LaA[n],2))
    SegLength(n) = real(word($LaA[n],3))
    SegAngle(n)  = real(word($LaA[n],4))

    # create equidistant datapoints along path
    set print $DashSingleCol
        Dist = 8                    # Distance between symbols
        N = floor(Total/Dist)
        idx = 2
        L0 = 0
        L = SegLength(idx)
        do for [i=0:N] {
            R = i*Dist
            while (L-R<0) {
                L0 = L
                idx = idx + 1
                L = L + SegLength(idx)
            }
            print sprintf("%.0f %g", PixToX(X0(idx)+(R-L0)*cos(SegAngle(idx))), \
                                   PixToY(Y0(idx)+(R-L0)*sin(SegAngle(idx))))
        }
    set print
    set print $DashMultipleCols append
        print $DashSingleCol
        print "\n\n"
    set print
}

pause -1 

mySymbol(n) = int(word("1 6 8",n))

plot for [i=1:words(colsY)] $DashMultipleCols u 1:2:(mySymbol(i)) index i-1 \
          w p pt mySymbol(i) ps 0.6 lc "black" ti sprintf("Column %s, pointtype %d",word(colsY,i),mySymbol(i))
### end of code

结果:

在此处输入图像描述

在此处输入图像描述

Edit: Since I changed the question title to "...different pointtypes...", I should show how to do it with multiple columns and different pointtypes.
The data of multiple columns is interpolated along the path and appended to the datablock $DashMultipleCols as (sub-)blocks which can later be addressed via index. I leave it up to you to decide whether solid/dash/dotted or plus/circle/triangle is easier to distinguish.

The following example creates a datablock with equidistant points along a given path.

  • for illustration some random test data is created with 1 x-column and 3 y-columns

  • for comparison the first graph is with solid, dashed and dotted lines. To my opinion the lines can be well distinguished, but you asked for "dashing" with a symbol.

  • for the second plot the data of columns 2,3,4 is "dashed" with the pointtypes 1,6,8, respectively.

  • the distance between the symbols is set by a variable, here: Dist = 8

  • in order to get a visually equal distribution, coordinate conversions from x,y to pixel coordinates and reverse are used. For this, the gnuplot variables GPVAL... are used which are available after plotting. That's why it is necessary to plot twice. The command pause -1 can be removed.

  • this works for linear axes (would need adjustment for logarithmic axes)

  • Your data is timedata. The code needs to be adjusted accordingly.

Code: (tested with wxt terminal)

### "dashing" with symbols equidistantly along a path
reset session

# create some random test data
set print $Data
    x0 = 0
    y0 = y1 = y2 = 100
    do for [i=1:10] {
        print sprintf("%g %g %g %g", x0=x0+int(rand(0)*10)+5, y0=y0+int(rand(0)*10)-5, y1=y1+int(rand(0)*10)-5, y2=y2+int(rand(0)*10)-5)
    }
set print

set key top left Left reverse
# plot to get the GPVAL_ ... values
plot $Data u 1:2 w l dt 1 lc "black" ti "Column 2, solid", \
        '' u 1:3 w l dt 2 lc "black" ti "Column 3, dashed", \
        '' u 1:4 w l dt 3 lc "black" ti "Column 4, dotted"

# store GPVAL parameters after plot in variables
txmin = GPVAL_TERM_XMIN
txmax = GPVAL_TERM_XMAX
tymin = GPVAL_TERM_YMIN
tymax = GPVAL_TERM_YMAX
xmin  = GPVAL_X_MIN
xmax  = GPVAL_X_MAX
ymin  = GPVAL_Y_MIN
ymax  = GPVAL_Y_MAX

# x,y to pix and pix to x,y coordinate conversion
XtoPix(x)    = txmin + real(x-xmin)    *(txmax-txmin)/( xmax- xmin)
YtoPix(y)    = tymin + real(y-ymin)    *(tymax-tymin)/( ymax- ymin)
PixToX(scrx) =  xmin + real(scrx-txmin)*( xmax- xmin)/(txmax-txmin)
PixToY(scry) =  ymin + real(scry-tymin)*( ymax- ymin)/(tymax-tymin)

# get lengths and angles in pixel coordinates
set angle degrees
Length(x0,y0,x1,y1) = sqrt((x1-x0)**2 + (y1-y0)**2)
Angle(x0,y0,x1,y1)  = (_dx=x1-x0, _dy=y1-y0, _L=sqrt(_dx**2 + _dy**2), _L==0 ? NaN : \
                      (_dy>=0 ? acos(_dx/_L) : 360-acos(_dx/_L) ))

colX  = 1
colsY = "2 3 4"         # multiple y-columns
do for [colY in colsY] {
    set table $LaA      # table for length and angles
        Total = 0
        plot x1=y1=NaN $Data u (x0=x1,x1=XtoPix(column(colX)),x0):\
                               (y0=y1,y1=YtoPix(column(int(colY))),y0):\
                (L=Length(x0,y0,x1,y1)):(L==L ? Total=Total+L : 0, Angle(x0,y0,x1,y1)) w table
    unset table
    X0(n)        = real(word($LaA[n],1))
    Y0(n)        = real(word($LaA[n],2))
    SegLength(n) = real(word($LaA[n],3))
    SegAngle(n)  = real(word($LaA[n],4))

    # create equidistant datapoints along path
    set print $DashSingleCol
        Dist = 8                    # Distance between symbols
        N = floor(Total/Dist)
        idx = 2
        L0 = 0
        L = SegLength(idx)
        do for [i=0:N] {
            R = i*Dist
            while (L-R<0) {
                L0 = L
                idx = idx + 1
                L = L + SegLength(idx)
            }
            print sprintf("%g %g", PixToX(X0(idx)+(R-L0)*cos(SegAngle(idx))), \
                                   PixToY(Y0(idx)+(R-L0)*sin(SegAngle(idx))))
        }
    set print
    set print $DashMultipleCols append
        print $DashSingleCol
        print "\n\n"
    set print
}

pause -1 

mySymbol(n) = int(word("1 6 8",n))

plot for [i=1:words(colsY)] $DashMultipleCols u 1:2:(mySymbol(i)) index i-1 \
          w p pt mySymbol(i) ps 0.6 lc "black" ti sprintf("Column %s, Symbol %d",word(colsY,i),mySymbol(i))
### end of code

Result:

enter image description here

enter image description here

Addition: Code adapted for time format

The time in gnuplot is nothing else than seconds passed since Jan 1st, 1970 00:00:00. If you enter in the gnuplot console print time(0) (which is the current time) you will get something like 1646757721, so about 1.6 billion seconds have passed since then until today.

The main differences and things to keep in mind compared to the above code:

  • define your specific time format, e.g. myTimeFmt = "%Y %b %d"
  • with this time format and the spaces inbetween, your data will be in columns 4,5, and 6.
  • for plotting the data the first time you use, e.g. plot $Data u (timecolumn(1,myTimeFmt)):4 w l
  • for the length and angle table ($LaA) you also have to use columns 4,5,6 and timecolumn() as well, i.e. plot x1=y1=NaN $Data u (x0=x1,x1=XtoPix(timecolumn(colX,myTimeFmt)),x0)
  • for creating the datablock $DashSingleCol you have to force the format for the time to be "%.0f" i.e. print sprintf("%.0f %g", PixToX(X0(idx)+(R-L0)*cos(SegAngle(idx))). Otherwise, with "%g" gnuplot would write a floating point number with exponent but only 6 digits, e.g. 1.64676e+09 which would be unwanted truncation or rounding.
  • for plotting $DashMultipleCols you can simply use u 1:2 because the time is already in seconds and does not have to be changes via timecolumn().

I hope this additional code and the explanations will help you to "dash" your data with different symbols.

Code:

### "dashing" with symbols equidistantly along a path (with timedata)
reset session

myTimeFmt = "%Y %b %d"

# create some random test data
set print $Data
    t0 = time(0)
    y0 = y1 = y2 = 10
    SecsPerDay =  24*3600   # seconds per day
    do for [i=1:10] {
        t0=t0+int(rand(0)*10*SecsPerDay)+5*SecsPerDay
        print sprintf("%s %g %g %g", strftime(myTimeFmt,t0), \
                y0=y0+int(rand(0)*10)-5, y1=y1+int(rand(0)*10)-5, y2=y2+int(rand(0)*10)-5)
    }
set print

set key top left Left reverse
# plot to get the GPVAL_ ... values
set format x "%b %01d\n%Y" timedate
plot $Data u (timecolumn(1,myTimeFmt)):4 w l dt 1 lc "black" ti "Column 4, solid", \
        '' u (timecolumn(1,myTimeFmt)):5 w l dt 2 lc "black" ti "Column 5, dashed", \
        '' u (timecolumn(1,myTimeFmt)):6 w l dt 3 lc "black" ti "Column 6, dotted"

# store GPVAL parameters after plot in variables
txmin = GPVAL_TERM_XMIN
txmax = GPVAL_TERM_XMAX
tymin = GPVAL_TERM_YMIN
tymax = GPVAL_TERM_YMAX
xmin  = GPVAL_X_MIN
xmax  = GPVAL_X_MAX
ymin  = GPVAL_Y_MIN
ymax  = GPVAL_Y_MAX

# x,y to pix and pix to x,y coordinate conversion
XtoPix(x)    = txmin + real(x-xmin)    *(txmax-txmin)/( xmax- xmin)
YtoPix(y)    = tymin + real(y-ymin)    *(tymax-tymin)/( ymax- ymin)
PixToX(scrx) =  xmin + real(scrx-txmin)*( xmax- xmin)/(txmax-txmin)
PixToY(scry) =  ymin + real(scry-tymin)*( ymax- ymin)/(tymax-tymin)

# get lengths and angles in pixel coordinates
set angle degrees
Length(x0,y0,x1,y1) = sqrt((x1-x0)**2 + (y1-y0)**2)
Angle(x0,y0,x1,y1)  = (_dx=x1-x0, _dy=y1-y0, _L=sqrt(_dx**2 + _dy**2), _L==0 ? NaN : \
                      (_dy>=0 ? acos(_dx/_L) : 360-acos(_dx/_L) ))

colX  = 1
colsY = "4 5 6"         # multiple y-columns
do for [colY in colsY] {
    set table $LaA      # table for length and angles
        Total = 0
        plot x1=y1=NaN $Data u (x0=x1,x1=XtoPix(timecolumn(colX,myTimeFmt)),x0):\
                               (y0=y1,y1=YtoPix(column(int(colY))),y0):\
                (L=Length(x0,y0,x1,y1)):(L==L ? Total=Total+L : 0, Angle(x0,y0,x1,y1)) w table
    unset table
    X0(n)        = real(word($LaA[n],1))
    Y0(n)        = real(word($LaA[n],2))
    SegLength(n) = real(word($LaA[n],3))
    SegAngle(n)  = real(word($LaA[n],4))

    # create equidistant datapoints along path
    set print $DashSingleCol
        Dist = 8                    # Distance between symbols
        N = floor(Total/Dist)
        idx = 2
        L0 = 0
        L = SegLength(idx)
        do for [i=0:N] {
            R = i*Dist
            while (L-R<0) {
                L0 = L
                idx = idx + 1
                L = L + SegLength(idx)
            }
            print sprintf("%.0f %g", PixToX(X0(idx)+(R-L0)*cos(SegAngle(idx))), \
                                   PixToY(Y0(idx)+(R-L0)*sin(SegAngle(idx))))
        }
    set print
    set print $DashMultipleCols append
        print $DashSingleCol
        print "\n\n"
    set print
}

pause -1 

mySymbol(n) = int(word("1 6 8",n))

plot for [i=1:words(colsY)] $DashMultipleCols u 1:2:(mySymbol(i)) index i-1 \
          w p pt mySymbol(i) ps 0.6 lc "black" ti sprintf("Column %s, pointtype %d",word(colsY,i),mySymbol(i))
### end of code

Result:

enter image description here

enter image description here

坏尐絯℡ 2025-01-17 15:43:54

设置xdata时间就可以了。 set timefmt myTimeFmt 仅适用于设置具有相同时间日期格式的 xrange 和 xtics。然后,在绘图之前,必须根据要绘图的文件的时间日期格式(即 $DashMultipleCols)修改 set timefmt ,在本例中为秒;因此设置timefmt“%s”

set xdata time is just fine. set timefmt myTimeFmt is ok ONLY for setting xrange and xtics with that same timedate format. Then, right before plotting, set timefmt must be modified according to the timedate format of the file to plot (that is, $DashMultipleCols), which in this case is seconds; therefore set timefmt "%s".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文