I have a binary data file containing a header followed by a bunch of five-byte data records. Each byte is the measurement of a different quantity, all taken at the same time1. I want to display a graph with five lines, showing how each quantity changes over time. The start time of the data file is encoded in some bytes at the beginning of the file, and I know that each record is taken 2 seconds after the previous one, but the records don't have a separate timestamp.
I can get this to plot more-or-less like I want by ignoring the actual time completely; if you set xdata time, then gnuplot does the Right Thing. However, it can't display the Right Time. On the other hand, if you set xrange ["*time1*":"*time2*"], then you get no graphs at all, because gnuplot doesn't know that the un-timestamped records correspond to those times.
Is there a way to tell gnuplot that binary records in a file start with a particular timestamp, so that they get matched up to the correct xrange?
My binary data (50-byte header = 0003 signature, uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute, uint8 second, other random stuff, then 5-byte records):
00000000 03 00 e3 07 0b 0f 16 22 13 63 97 00 00 fc 78 00 |.......".c....x.|
00000010 00 60 5c 04 00 00 00 00 00 63 00 00 00 00 00 00 |.`\......c......|
00000020 00 00 00 00 00 00 00 00 ff ff ff 00 00 ff ff ff |................|
00000030 00 00 61 3a 00 00 00 61 3a 00 00 00 61 3b 00 00 |..a:...a:...a;..|
00000040 00 61 3b 00 00 00 60 3c 00 00 00 60 3c 00 00 00 |.a;...`<...`<...|
00000050 60 3c 00 00 00 60 3c 00 00 00 60 3d 00 00 00 60 |`<...`<...`=...`|
00000060 3d 00 00 00 60 3c 00 00 00 60 3c 00 00 00 61 3e |=...`<...`<...a>|
00000070 00 00 00 61 3e 00 00 00 61 3f 00 00 00 61 3f 00 |...a>...a?...a?.|
00000080 00 00 61 3f 00 02 00 61 3f 00 02 00 61 3f 00 01 |..a?...a?...a?..|
00000090 00 61 3f 00 01 00 61 3f 00 00 00 61 3f 00 00 00 |.a?...a?...a?...|
000000a0 61 3f 00 00 00 61 3f 00 00 00 61 41 00 01 00 61 |a?...a?...aA...a|
000000b0 41 00 01 00 60 42 00 00 00 60 42 00 00 00 60 40 |A...`B...`B...`@|
000000c0 00 00 00 60 40 00 00 00 60 3d 00 00 00 60 3d 00 |...`@...`=...`=.|
000000d0 00 00 60 3c 00 00 00 60 3c 00 00 00 60 3c 00 00 |..`<...`<...`<..|
000000e0 00 60 3c 00 00 00 60 3c 00 00 00 60 3c 00 00 00 |.`<...`<...`<...|
000000f0 60 3d 00 00 00 60 3d 00 00 00 60 3e 00 00 00 60 |`=...`=...`>...`|
00000100 3e 00 00 00 60 3e 00 00 00 60 3e 00 00 00 60 3f |>...`>...`>...`?|
00000110 00 00 00 60 3f 00 00 00 60 40 00 00 00 60 40 00 |...`?...`@...`@.|
00000120 00 00 60 40 00 05 00 60 40 00 05 00 60 40 00 04 |..`@...`@...`@..|
00000130 00 60 40 00 04 00 60 3f 00 00 00 60 3f 00 00 00 |.`@...`?...`?...|
00000140 60 40 00 00 00 60 40 00 00 00 60 3f 00 00 00 60 |`@...`@...`?...`|
00000150 3f 00 00 00 60 3e 00 00 00 60 3e 00 00 00 60 3e |?...`>...`>...`>|
00000160 00 0f 00 60 3e 00 0f 00 60 3c 00 00 00 60 3c 00 |...`>...`<...`<.|
00000170 00 00 60 3d 00 00 00 60 3d 00 00 00 60 3e 00 01 |..`=...`=...`>..|
00000180 00 60 3e 00 01 00 60 3e 00 18 00 60 3e 00 18 00 |.`>...`>...`>...|
00000190 60 3e 00 02 00 60 3e 00 02 00 60 3e 00 03 00 60 |`>...`>...`>...`|
My gnuplot script:
#!/usr/bin/gnuplot
fn="20191115223419"
set title "Heart Rate, O2, Motion"
set xlabel "Time"
set xdata time
set timefmt "%Y%m%d%H%M%S"
set xrange ["20191115223419":"20191116071015"]
set format x "%H:%M"
set yrange [40:120] # Heart rate
set y2range [50:100] # O2 saturation
plot \
fn binary skip=0x32 format="%5uint8" using 0:2 with lines lt rgb "red" title "HR", \
fn binary skip=0x32 format="%5uint8" using 0:(($4)/4+40) with lines lt rgb "orange" title "Motion", \
fn binary skip=0x32 format="%5uint8" using 0:1 with lines lt rgb "gray60" title "O2" axes x1y2
pause -1 "Hit <ENTER> to continue..."
It plots as desired if I comment out the xrange line.
I know I could easily write a script to munge the data into better form, and perhaps that's the thing to do: Python it into a better string, then gnuplot that. But I'd be delighted if I could just tell gnuplot alone to do what I want.
1The 5 bytes are actually O2 saturation, pulse rate, dummy (always zero), motion sensor, and another dummy byte. My gnuplot script only plots the 3 non-dummy values.
