Grace Sawyer
Grace Sawyer

Reputation: 395

Multiple Gnuplots within figure giving incorrect colors

I'm trying to plot 3 data sets, each a different color, on one plot, but my code coloring seems to always incorrecty assign the last set's color also to the middle set:

set terminal png
set datafile separator ","

set title "Hours slept"
set xlabel "Date"
set ylabel "Hours"
set output '1.png'
set xdata time
set timefmt "%m/%d/%y"
set xrange ["09/17/22":"11/12/22"]
set format x "%m/%d"
set style line 1 lt 1 linecolor rgb "blue" lw 2 pt 1
set style line 2 lt 2 linecolor rgb "red" lw 2 pt 1
set style line 3 lt 3 linecolor rgb "yellow" lw 2 pt 1

plot "< grep -e '\*' fraction.csv | sed 's/*//'" using 1:($4) title 'weekends' ls 1 with points, \
"< grep -e '^[0-9]' fraction.csv" using 1:($4) title 'weekdays' ls 2 with points, \
"< grep -e '\^' fraction.csv | sed 's/^//'" using 1:($4) title 'fridays' ls 3 with points

enter image description here

There are suddenly no reds (the middle plot). When I remove just the 3rd friday plot (last line), it looks like this: enter image description here

So clearly I'm doing the coloring wrong? With three plots, all the weekdays become yellow instead of red.

This weird bug is driving me crazy. I initially did it like this without the explicit styles:

"< grep -e '^[0-9]' fraction.csv" using ($1):($3) title 'weekends' with points lc rgb 'blue'

And the same exact problem happened. When I run each of the 3 grep calls they are all distinct data sets and there are far more weekday points than the other two.

Upvotes: 0

Views: 81

Answers (1)

theozh
theozh

Reputation: 25734

I don't have your data, so, the following script creates some random test data. Why do you use grep and sed if you can do it with gnuplot only? Check help tm_wday which returns a number for the weekdays (0-6) for Sunday to Saturday. Define a function which sets the color accordingly. For the legend you can use keyentry (check help keyentry).

Addition: more explanations

I didn't have an clue about your gnuplot level, I thought you could adapt the example to your case. Well, there is for almost every command, function, keyword a help entry in gnuplot. In the gnuplot console type help <keyword>.

  • myColor(t) = ..., defines a function using the ternary operator which returns a color in the format 0xRRGGBB depending on the weekday, check help ternary, help tm_wday, help colorspec.
  • set format x "%m/%d" timedate will format the x-axis as time axis, check help time_specifiers.
  • ...(t=timecolumn(1,myTimeFmt))... in gnuplot date/time is handled as seconds passed since1970-01-01 00:00:00, check help timecolumn.
  • ...lc rgb var, sets the color from the data (or function), check help lc variable.
  • list your weekday categories in a string and address them by index via word check help word.
  • for the keyentry use a loop (check help for and help keyentry) and get the color from the weekday number. 1970-01-01 was a Thursday (=4). So, subtract 24*3600 seconds (=1 day) in order to get from the indices 1,2,3 to the weekday numbers 4,5,6 (Thu,Fri,Sat) (=weekdays, fridays, weekends) which will return the colors (red, yellow, blue).

Ok, so I modified the code such that you just have to

  1. skip the random data creation section
  2. replace $Data with '<YourFilename>', i.e. in your case 'fraction.csv'.

Script:

### color days of the week differently
reset session

myTimeFmt = "%m/%d/%y"

# create some random test data
set table $Data separator comma
    t0 = time(0)
    plot '+' u (strftime(myTimeFmt,t0+$0*24*3600)):(invnorm(rand(0))+7) w table
unset table

set datafile separator comma
set key noautotitle
set yrange[0:12]
set format x "%m/%d" timedate
myColor(t) = (d=tm_wday(t), d==5 ? 0xffff00 : d==6 || d==0 ? 0x0000ff : 0xff0000)
myDay(i)   = word("weekdays fridays weekends",i)

plot $Data u (t=timecolumn(1,myTimeFmt)):2:(myColor(t)) w p pt 13 lc rgb var, \
     for [i=1:3] keyentry w p pt 13 lc rgb myColor((i-1)*24*3600) ti myDay(i)
### end of script

Result:

enter image description here

Upvotes: 1

Related Questions