编辑:由于我将问题标题更改为“...不同 pointtypes...”,我应该展示如何使用多个列和不同的pointtypes .
多列的数据沿路径插入,并作为(子)块附加到数据块$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
结果: