日付時刻データ
よくあるシチュエーションは x 軸または y 軸のどちらか一方が日付時刻を表現していることだ. このとき, データには一種類のフォーマットで日付時刻が書かれていることになる. gnuplot はこれをサポートしていて, x/y 軸が日付時刻を表していることと, パースに用いるフォーマットを指定すれば読むことが出来る.
本章の最後でも触れるが, 異なるデータフォーマットが混在している場合, 例えば x/y 軸両方ともが日付時刻であってそれぞれ違う書き方がなされている場合は, 出来なくはないが, 直接のサポートがなされてはいない.
日付時刻であることの宣言
x/y 軸それぞれについて日付時刻データであることは次で宣言する.
set xdata time
set ydata time
timefmt
日付時刻データだと宣言された値はデフォルトでは
"%d/%m/%y,%H:%M"
だとしてパースが行われる.
このフォーマットは,
set timefmt <format>
として自由に宣言できる.
また xtics
ytics
の表示に使うフォーマットは, これとは別に宣言できて, 次のようにする.
set format x <format>
set format y <format>
この <format>
は先程の timefmt
で使う <format>
と全く同じ形式で記述する.
フォーマットは C 言語のように %-
指定子を含んだ文字列として指定する.
%-
指定子
format | explanation |
---|---|
%d | 日 (1-31) |
%m | 月 (1-12) |
%y | 年の下2桁 (0-99) |
%Y | 年の4桁 |
%j | day of the year (1-365) |
%H | 時 (0-24) |
%M | 分 (0-60) |
%S | 秒 (0-60) |
%s | UNIX time |
%B | 月の英語表記 |
%b | 月の英語表記 (3文字省略形) |
NOTE. using
キーワード
gnuplot は plot するデータを読むとき, 一行をホワイトスペース文字で分割して, これの何番目を x データ, 何番目を y データという風に使っている.
ここで疑問になるのは, 空白文字を含む日付時刻データを表現できるのかということだ.
問題なく出来る.
timefmt
には空白文字を含んだフォーマットを指定すればよい.
ただし, plot コマンドは using
を要請してくるかもしれない.
これは明示的に何番目と何番目を x, y データにするかという指定である.
次のようなデータを考える.
2020-01-02 13:00 3.141592
これは
'%Y-%m-%d %H:%M'
というフォーマットの日付の後ろに一つの数値が続いている.
gnuplot はこのままでは3つの数値が並んでいると解釈する.
そこで初めの二つが x のための一塊の日付データであることを宣言する.
set xdata time
set timefmt '%Y-%m-%d %H:%M'
こうなるともともと二番目が y であるというデフォルトの設定が壊れるので, gnuplot はユーザーに明示することを求める. そこで, (もともとの分割で)1 番目が x で, 3 番目が y であると注釈して plot を行う.
plot 'data.txt' using 1:3
これで期待通りのプロットが得られた.
異なるフォーマットを共存させるには
x と y が異なるフォーマットの日付時刻データである,
或いは複数のデータを同時にプロットさせるに当たって別のフォーマットが使われてるなどの場合,
異なるフォーマットを指定したくなる.
しかし set timefmt
は設定を上書きするだけであって, x と y のパースに異なるフォーマットを与える事はできない.
やや強引にやってやれないことはない.
https://stackoverflow.com/a/31009235
が参考になった.
using
の中で strptime
関数を直接呼び出せばよい.
gnuplot 5.0
以上ならより簡素な timecolumn
関数の方が便利
Example
timecolumn
関数を使って, x, y で別のフォーマットが使われているデータをプロットする.
# x = %Y-%m-%d
# y = %H:%M:%S
$data << EOD
2017-10-23 13:43:00
2017-10-24 14:37:45
2017-10-25 14:18:06
2017-10-26 14:31:48
2017-10-27 12:12:41
2017-10-30 13:56:49
EOD
set xdata time
set ydata time
xformat = '%Y-%m-%d' # parse format (for timecolumn)
yformat = '%H:%M:%S'
set format x '%m/%d' # tics format
set format y '%H:%M'
plot $data using (timecolumn(1, xformat)):(timecolumn(2, yformat)) w lp