Как установить переменную ширину линии при построении?

Я хотел бы построить кривую с переменной шириной линии. Я обычно делал бы следующее, если бы я хотел использовать точки вместо линии:

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

1

Пока в gnuplot нет переменной ширины линии. Кроме того, если в ваших данных есть точки, у вас будетлинии, хотя, вы даетеширины линий в ваших данных. Какая ширина линии какой точки данных должна быть пропущена? Первый или последний? Если вы рисуете конические линии, у вас нет этой проблемы. Для этого вы можете использовать fillcurves, но, как упомянул @Ilya Zakharevich, решение @Gavin Portwood на самом деле отображает высоту строки , а не ширину линии .

В приведенном ниже решении также используются заполненные кривые, но с реальной шириной линий. Для этого вам нужно перейти к координатам пикселей, выполнить некоторые вычисления и вернуться к координатам оси (пока не будет работать для логарифмического масштаба). 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

Результат:

Это решает проблему с ответом Гэвина: его метод создает определенную высоту строки (в отличие от ширины строки). Я нашел другой способ, который работает с шириной.

Недостатки моего решения: нужно заранее знать "соотношение сторон координатного пространства", есть артефакты на стыках.

Другие вопросы по тегам