Как установить переменную ширину линии при построении?
Я хотел бы построить кривую с переменной шириной линии. Я обычно делал бы следующее, если бы я хотел использовать точки вместо линии:
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?
3 ответа
Ты прав что linewidth
не принимает var
лайк pointsize
делает. Но вы можете получить аналогичный эффект, используя filledcurves
:
WIDTH_FACTOR=20
plot 'curve.dat' u ($1):($2+$1/WIDTH_FACTOR):($2-$1/WIDTH_FACTOR) w filledcurves
Пока в gnuplot нет переменной ширины линии. Кроме того, если в ваших данных есть точки, у вас будет
В приведенном ниже решении также используются заполненные кривые, но с реальной шириной линий. Для этого вам нужно перейти к координатам пикселей, выполнить некоторые вычисления и вернуться к координатам оси (пока не будет работать для логарифмического масштаба). gnuplot может легко заполнить кривые между двумя значениями y одинаковыми значениями x, что, однако, здесь не поможет. Но gnuplot также может заполнять замкнутые кривые . Следовательно, сценарий создает замкнутую кривую, сначала создавая «левый» контур пути, а затем перевернутый «правый» контур пути. Поскольку скрипт использует индексирование блоков данных, для него требуется gnuplot>=5.2.0.
Скрипт: (работает с gnuplot>=5.2.0, сентябрь 2017 г.)
### variable linewidth / tapered lines plot
reset session
$Data <<EOD
1 1 1.0
9 2 25.0
2 3 15.0
4 2 5.0
7 4 5.0
3 7 1.0
2 5 25.0
4 4 3.0
7 7 30.0
9 4 80.0
EOD
set size ratio -1
set angle degrees
set key noautotitle
# plot data to get GPVAL_... values
plot $Data u 1:2 w l
# terminal constants
xmin = GPVAL_X_MIN
ymin = GPVAL_Y_MIN
xtmin = GPVAL_TERM_XMIN
ytmin = GPVAL_TERM_YMIN
Factor = GPVAL_VERSION==5.2 && int(GPVAL_PATCHLEVEL)<=7 ? \
GPVAL_TERM eq "wxt" ? 20 : GPVAL_TERM eq "qt" ? 10 : 1 : 1
Rxaupu = (GPVAL_X_MAX-xmin)/(GPVAL_TERM_XMAX-xtmin)*Factor # x ratio axes units to pixel units
Ryaupu = (GPVAL_Y_MAX-ymin)/(GPVAL_TERM_YMAX-ytmin)*Factor # y
ax2px(x) = (x-xmin)/Rxaupu + xtmin # x axes coordinates to pixel coordinates
ay2py(y) = (y-ymin)/Ryaupu + ytmin # y
px2ax(x) = (x-xtmin)*Rxaupu + xmin # x pixel coordinates to axes coordinates
py2ay(y) = (y-ytmin)*Ryaupu + ymin # y
# convert into pixel coordinates
set table $PixelCoords
plot $Data u (ax2px($1)):(ay2py($2)):3 w table
unset table
# various functions
x(i) = word($PixelCoords[i],1)
y(i) = word($PixelCoords[i],2)
lw(i) = word($PixelCoords[i],3)
a(i,j) = a2(x(i),y(i),x(j),y(j))
a2(x0,y0,x1,y1) = atan2(y1-y0,x1-x0)+90
dx(i) = lw(i)*0.5*cos(a)
dy(i) = lw(i)*0.5*sin(a)
set print $Outlines
do for [i=1:|$PixelCoords|-1] {
a = a(i,i+1)
do for [j=i:i+1] {
print sprintf("%g %g", px2ax(x(j)+dx(j)), py2ay(y(j)+dy(j)))
}
}
do for [i=|$PixelCoords|:2:-1] {
a = a(i,i-1)
do for [j=i:i-1:-1] {
print sprintf("%g %g", px2ax(x(j)+dx(j)), py2ay(y(j)+dy(j)))
}
}
set print
set style fill solid 1.0 noborder
set grid x,y
plot $Outlines u 1:2 w filledcurves fc "web-green"
### end of script
Результат:
Это решает проблему с ответом Гэвина: его метод создает определенную высоту строки (в отличие от ширины строки). Я нашел другой способ, который работает с шириной.
Недостатки моего решения: нужно заранее знать "соотношение сторон координатного пространства", есть артефакты на стыках.