1

Similar to Gnuplot combing multiple value types in one line graph with different colours and dashes, but this time I want to plot two lines, with the color/key based on the third column:

$sample <<EOD
2020-02-01 1 Foo
2020-02-01 1 Bar
2020-03-01 5 Foo
2020-03-01 5 Bar
2020-04-01 10 Foo
2020-04-01 20 Bar
EOD

set xdata time
set timefmt "%Y-%m-%d"

plot $sample using 1:2 with lines

I.e. using lc variable and not a equality filter. I don't grok how lc variable works.

Bonus: Instead of line color being variable, could the dash types be variable? I.e. based on a newly introduced fourth column?

hendry
  • 9,725
  • 18
  • 81
  • 139
  • as far as I know you can have pointsize, pointtype and linecolor variable (check `help points`), but not linewidth or dashtype. Maybe there is some workaround? – theozh Aug 26 '20 at 09:32

2 Answers2

2

It wouldn't normally make sense to take a line or dash type from a data column because that implies it would be changing for each point along the line. So I will assume that's not really what you want (although it is possible to do if needed). The usual case is that each clause of the plot command gets a separate line type. You can redefine the dash patterns for these line types as you like, along with any other properties. Here I change the line width as well as the dash type but leave the default colors unchanged.

set linetype 1 lw 1 dashtype '-'
set linetype 2 lw 1 dashtype '.-'
set linetype 3 lw 2 dashtype '..-'
set linetype 4 lw 2 dashtype '._._'

# limit variable linetype to 1-4
ltvar(lt) = 1 + int(lt-1) % 4

set xrange [0:10]
plot for [i=1:8] '+' using ($1):(i * $1) with lines linetype ltvar(i) title sprintf("Line %d",i)

enter image description here

Ethan
  • 13,715
  • 2
  • 12
  • 21
1

You have to filter your data as well, because I assume that you don't want a single alternating colored line but two separated and separately colored lines. I modified your test data because the original would be a bit unfortunate for illustration. For using lc var you have to provide a number which you can do e.g. via defining a function myColor().

Code:

### filtering data and apply color
reset session

$sample <<EOD
2020-02-01 1 Foo
2020-02-01 7 Bar
2020-03-01 5 Foo
2020-03-01 9 Bar
2020-04-01 10 Foo
2020-04-01 20 Bar
EOD

set key top left
myTimeFmt = "%Y-%m-%d"
set format x "%Y\n%m\n%d" timedate
myFilter(dcol,fcol,key) = strcol(fcol) eq key ? column(dcol) : NaN
set datafile missing NaN
myColor(col) = strcol(col) eq "Foo" ? 0xff0000 : strcol(col) eq "Bar" ? 0x0000ff : 0x000000
keys = "Foo Bar"

plot for [key in keys] $sample u (timecolumn(1,myTimeFmt)):(myFilter(2,3,key)):\
    (myColor(3)) w lp pt 7 lc rgb var title key
### end of code

Result:

enter image description here

Addition: (you can mimic a hash or lookup table)

keys = "Foo Bar Xyz"
myColorList = "0xff0000 0x0000ff 0x000000"
myColor(s) = (tmp=NaN, sum [i=1:words(keys)] (word(keys,i) eq s ? (tmp=word(myColorList,i),0) : 0), int(tmp))

plot for [key in keys] $sample u (timecolumn(1,myTimeFmt)):(myFilter(2,3,key)):\
    (myColor(key)) w lp pt 7 lc rgb var title key

Example:

print myColor("Foo")   # result will be 16711680 which is 0xff0000 in hex
theozh
  • 22,244
  • 5
  • 28
  • 72
  • Be great if you could add a key, blue for bar, red for foo – hendry Aug 26 '20 at 12:27
  • in the plot command simply replace `notitle` with `title key`. Actually, `key` and `keys` might not be smart variables, but I guess there is no risk to mix it up with `set key`. – theozh Aug 26 '20 at 12:43
  • Instead of `"Foo" ? 0xff0000 : strcol(col) eq "Bar" ? 0x0000ff` isn't there a generic color hash function? Like how https://stackoverflow.com/questions/62806241/dynamically-colored-bar-charts-in-gnuplot/62823958#comment111183085_62823958 works (I think!) – hendry Aug 27 '20 at 01:21
  • you are referring to `...:($0+1) ...lc var` ? Ok, but `$0` is the row number and each line segment gets a different color. You have strings as input: `Foo`, `Bar`. You need to define a function to return a number from your string as input. gnuplot supports variables and arrays but not hashes. You can build your own hash function: that's what I've done above with the ternary operator and just two values. If you have many values this will get lengthy and difficult to read. There might be workarounds. You could also use a palette for color, but there the input is also numbers, not strings. – theozh Aug 27 '20 at 04:26