绘图时如何设置可变线宽?

问题描述 投票:0回答:3

我想绘制一条线宽可变的曲线。如果我想使用点而不是线,我通常会执行以下操作:

gnuplot> plot 'curve.dat' u ($1):($2):($1) ps var

其中 curve.dat 填充有:

0  0
1  1
2  4
3  9
4  16
5  25

等等。现在,如果我尝试类似的线宽

gnuplot> plot 'curve.dat' u ($1):($2):($1) lw var

我收到错误消息:

undefined variable: var

或者这是 gnuplot 无法完成的事情?

gnuplot
3个回答
3
投票

你是对的,

linewidth
不像
var
那样接受
pointsize
。但是你可以通过使用
filledcurves
:

来达到类似的效果
WIDTH_FACTOR=20
plot 'curve.dat' u ($1):($2+$1/WIDTH_FACTOR):($2-$1/WIDTH_FACTOR) w filledcurves

1


1
投票

这解决了加文答案的一个问题:他的方法创建了一定的线高(而不是线宽)。我找到了一种不同的方法,它适用于widths

我的解决方案的缺陷:需要提前知道“坐标空间长宽比”,并且连接处存在伪影。


1
投票

到目前为止,gnuplot 中还没有可变线宽。 此外,如果您的数据有

N
点,您将有
N-1
线,尽管您在数据中给出了
N
线宽。应跳过哪个数据点的哪个线宽?第一个还是最后一个? 如果你画锥形线,你就不会遇到这个问题。您可以为此使用 fillcurves,但正如 @Ilya Zakharevich 提到的,@Gavin Portwood 的解决方案实际上是绘制 line height,而不是 line width

下面的解决方案也使用填充曲线,但绘制真实的线宽。为此,您必须转到像素坐标,进行一些计算并返回到轴坐标(尚不适用于对数刻度)。 gnuplot 可以轻松地用相同的 x 值填充两个 y 值之间的曲线,但这在这里没有帮助。但 gnuplot 也可以填充闭合曲线。因此,脚本通过创建路径的“右”轮廓和锥形“线”的反向“左”轮廓来创建闭合曲线。

编辑:完成修订

  • 使用数组代替数据块索引(两者都需要 gnuplot>=5.2.0)
  • 使用组合值
    x + j*y
    ,而不是 x 和 y 值的单独函数和变量,其中
    j = sqrt(-1)
    是虚数单位。这稍微缩短了脚本。

脚本:(适用于 gnuplot>=5.2.0,2017 年 9 月)

### variable linewidth / tapered lines plot 
reset session

$Data <<EOD
 1   10    1.0
 9   20   25.0
 2   30   15.0
 4   20    5.0
 7   40    5.0
 3   70    1.0
 2   50   25.0
 4   40    3.0
 7   70   30.0
 9   40   80.0
EOD

# plot data to get GPVAL_... values and number of rows
plot $Data u (r=$0+1,$1):2

j = {0, 1}  # imaginary unit
array P[r]
array LW[r]
stats $Data u (P[$0+1]=$1+j*$2, LW[$0+1]=$3) nooutput  # put data into arrays

# axes to pixel conversion and vice versa
Factor = GPVAL_VERSION==5.2 && int(GPVAL_PATCHLEVEL)<=7 ? \
         GPVAL_TERM eq "wxt" ? 20 : GPVAL_TERM eq "qt" ? 10 : 1 : 1
aMin   = GPVAL_X_MIN     + j*GPVAL_Y_MIN
pMin   = GPVAL_TERM_XMIN + j*GPVAL_TERM_YMIN
R      = Factor*((GPVAL_X_MAX-real(aMin))/(GPVAL_TERM_XMAX-real(pMin)) + \
            j*(GPVAL_Y_MAX-imag(aMin))/(GPVAL_TERM_YMAX-imag(pMin)))
a2p(a) = (real(a)-real(aMin))/real(R) + real(pMin) + j*((imag(a)-imag(aMin))/imag(R) + imag(pMin))
p2a(p) = (real(p)-real(pMin))*real(R) + real(aMin) + j*((imag(p)-imag(pMin))*imag(R) + imag(aMin))

# various functions in pixel coordinates
dp(i)   = a2p(P[i+1])-a2p(P[i])                     # distance between two points
ap(i)   = atan2(imag(dp(i)),real(dp(i))) + acos(0)  # perpendicular angle (independent of setting degrees or radians)
wp(i,k) = LW[k]*0.5*(cos(ap(i)) + j*sin(ap(i)))     # offset for outline

array OUTL[4*|P|-4]
do for [i=1:2*|P|-2] {
    m0 = (i-1)/2 + 1    # integer division!
    n0 = i/2 + 1        # 
    m1 = |P| - m0 
    n1 = |P| - n0 + 1
    OUTL[i]         = p2a(a2p(P[n0]) - wp(m0,n0))
    OUTL[i+2*|P|-2] = p2a(a2p(P[n1]) + wp(m1,n1))
}

set style fill noborder
set key noautotitle
set grid x,y

plot OUTL u (real(OUTL[$0+1])):(imag(OUTL[$0+1])) w filledcurves lc "web-green"
### end of script

评论:

  • qt
    终端中,结果看起来不同,这不是预期的方式,但我猜原因是图形库填充区域的方式。该脚本需要一些调整。
  • 对于
    pngcairo
    终端:由于您必须绘制两次(第一次获取
    GPVAL_...
    变量),您还必须设置文件名两次,即类似这样:
reset session
...
set term pngcairo
set output "SO52250137.png"
plot $Data u (r=$0+1,$1):2
set output "SO52250137.png"
...
plot OUTL u (real(OUTL[$0+1])):(imag(OUTL[$0+1])) w filledcurves lc "web-green"
set output
### end of script

结果:(来自

wxt
pngcairo
终端)

(从

qt
终端输出)

© www.soinside.com 2019 - 2024. All rights reserved.