5

I have a datafile that has three columns :

1 1.0 1
2 1.5 2
3 0.0 3
4 1.2 2.5
5 1.0 1
6 1.1 5

where the first column is my X value, the second column is my Y value, and the third column is the line width. I'd like for each line segment to be plotted according to the third column line width.

I tried:

plot 'file1.dat' using 1:2:3  with lines lw var

But I get undefined variable: var error.

Is this possible in gnuplot?

Thanks.

Tom Solid
  • 2,226
  • 1
  • 13
  • 32
Dark Templar
  • 1,175
  • 13
  • 27
  • A line segment is between two points. Both specify a different line width. Which one should be used? – Christoph Jun 20 '16 at 17:37
  • No in this form this is impossible with Gnuplot: as Christoph wrote there is an uncertainty what should be the line width so Gnuplot doesn't interpret "with lines lw variable". – Tom Solid Jun 20 '16 at 18:08

3 Answers3

4

If you define column 3 as the linewidth between points n and n+1 (so the value of col. 3 of the row will be ignored) you can cheat:

stat 'file1.dat'
n=STATS_records
plot for [i=0:0] 'file1.dat' using 1:2:(alma=$3) every ::i::i w l lc 1 lw 1
plot for [i=0:n-1] 'file1.dat' using 1:2:(alma=$3) every ::i::i+1 w l lc 1 lw alma notitle

OR

plot 'file1.dat' u 0:1
n=GPVAL_DATA_X_MAX
plot for [i=0:0] 'file1.dat' using 1:2:(alma=$3) every ::i::i w l lc 1 lw 1
plot for [i=0:n] 'file1.dat' using 1:2:(alma=$3) every ::i::i+1 w l lc 1 lw alma notitle

enter image description here

You need the first plot for[i=0:0] to 'initialize' variable 'alma'.

Tom Solid
  • 2,226
  • 1
  • 13
  • 32
  • Good solution! So you've decided that the linewith for `[i, i+1]` was the one in line `i`, maybe it's good to state it explicitly. Next there'll be a question to make tapered lines between two points! – Joce Jun 21 '16 at 10:38
  • Thank you very much for your answer! Indeed, you are right, the n dots create n-1 segments with width. I will consider the 0th width as 1 then. – Dark Templar Jun 21 '16 at 18:04
  • @Joce you want to kill me, don't you? :D – Tom Solid Jun 21 '16 at 19:13
  • @Joce I thought about using `filledcurves` for the tapered lines, but my results were wrong, because the line width must be applied vertically to the connecting lines, and not on the y-axis only. – Christoph Jun 22 '16 at 06:01
  • @Christoph: I'm not sure I get what the problem is, of course in any tapered broken line there is the question of how the connection is made at nodes, and having the taper along `y` rather than the normal will distort things when slope is large, but I'd think it'd still look OK? Or else one could calculate the y-equivalent of a normal taper, and add circles of correct radius at nodes! A summer of code project, nearly! – Joce Jun 22 '16 at 08:16
  • @TomSolid: BTW, why `alma` ? Your university, your girlfriend's name, your latin soul, a Hungarian apple or some mysterious abbreviation? :) – Joce Jun 22 '16 at 08:17
  • @Joce: 'alma' as 'apple' : ) Naming the variables after fruits in ABC order: 'apple, banana, lemon, walnut, strawberry...' (alma, banán, citrom, dió, eper) :D – Tom Solid Jun 22 '16 at 08:29
  • @JoceNoToPutinsWarInUkraine tapered lines are not impossible (see https://stackoverflow.com/a/73485567/7295599), but it requires gnuplot5.2. I haven't found yet a solution for the version at the time of OP's question. – theozh Aug 26 '22 at 04:32
1

As mentioned by @Christoph in the comments, you have N points (rows) and N linewidth values, but only N-1 connecting lines. So, you have to decide which linewidth value should be applied to which line. Which one to skip? The first one or the last one? Here, the last one is skipped.

It's basically, a shortened version of @Tom Solid's solution. Actually, you can get the initial value already during the stats command.

As @Joce mentioned and @Ilya Zakharevich is suggesting in his answer, if you do not fear some extra effort you can also draw tapered lines.

Data:

# x   y     linewidth
  1   1.0   1
  2   1.5   2
  3   0.0   3
  4   1.2   2.5
  5   1.0   1
  6   1.1   5

Script: (works with gnuplot 4.6.0, March 2012)

### workaround for variable linewidth
reset

FILE = "SO/SO37925489.dat"

stats FILE u ((N=$0)==0?Lw0=$3:0) nooutput
set grid

plot for [i=0:N] FILE u 1:2:(Lw0=$3) every ::i::i+1 w l lw Lw0 lc rgb "red" notitle
### end of script

Result:

enter image description here

theozh
  • 22,244
  • 5
  • 28
  • 72
0
stat 'varwidth.dat' nooutput
n=STATS_records; prex=0; prey=0; SC=2    # How y-axis is expanded relative to the x-axis
plot for [i=0:n-1] for [try=0:1] '' using 1:((try==0?dx=$1-prex:1),(try==0?sl=($2-prey)/(dx==0?1:dx):1),(try==0?prex=$1:1),(try==0?prey=$2:1),$2+(w=$3/80*sqrt(1+(SC*sl)**2))/2):($2-w/2) every ::i::i+1 w filledcurves lc 1 notitle

This produces the correct line width (as opposed to the “line height”, as in the answer to a related question). I have no clue how to make the “lines” match where they join (seems to be impossible without support from inside gnuplot).

(This assumes that the data in the question is in a file varwidth.dat.)
enter image description here

Ilya Zakharevich
  • 1,210
  • 1
  • 9
  • 6