最近のgnuplotは日付や時刻の情報を取得する関数time()
を持っていますので、簡単にこれらの情報を取得して使うことができます。また、時刻を文字列に変換する関数strftime()
関数も便利です。少し古いバージョンのgnuplotの場合はこれらの関数がありませんが、代替策としてWindowsコマンドを介して時刻等を取得する方法があります。
(2015/2/1: 以下で、日本とGMTとの時差を8時間と間違えて記述していたので、9時間に修正しました。N君、指摘どうもありがとうございます。)
日付や時刻の情報を取得するには、time()
関数を使います。この関数には幾つかの使い方があります。
まず、適当な数を引数に与えると、この関数は2000年1月1日からの経過時間を秒の単位で返します。時間はグリニッジ標準時(GMT)で計算されます。ここで、引数が整数の場合は帰ってくる値も整数値になり、引数が実数の場合は実数値になります。例えば、以下のようなスクリプトを実行してみましょう。
print time(0)
print time(0.0)
plot x #グラフウィンドウの表示用
すると、gnuplotのコマンドラインには以下のように表示されます。確かに、整数の引数0
を与えた場合は整数値が、実数の引数0.0
を与えた場合は実数値が返ってきていることが分かります。
464459304
464459304.127394
文字数を引数に取った場合、time()
関数は現在の時刻を文字列で指定されたフォーマットに直して文字列として返します。ただし、この時刻も、グリニッジ標準時での時刻です。例えば、以下のようなスクリプトを実行してみましょう。
print time("%Y/%m/%d %H:%M:%S")
plot x #ウィンドウ表示用
すると、コマンドラインには例えば以下のように表示されます。
2014/09/19 16:41:18
この例からわかるように、引数の中の%Y
は西暦年(4桁)、%m
は月、%d
は日、%H
は24時間表示の時、%M
は分、%S
は秒をそれぞれ出力することを意味します。ほかにも様々なフォーマット文字列がありますが、それらに関してはhelp time
を参照して下さい。
さて、上記コマンドで出てくる時刻はグリニッジ標準時ですので、日本の時刻より9時間遅れてしまっていることに注意して下さい。従って、上記の例は日本ではあまり使い道がありません。
上述の時差の問題を解決するには、time()
関数をstrftime()
関数と併用する必要があります。strftime()
関数は文字列引数と、数値の引数の二つを取ります。文字列引数は前述のtime()
関数で使うのと同様の数値のフォーマット文字列、数値の引数は2000年1月1日からの経過時間(秒)です。そして、時間をフォーマット文字列で変換した結果を文字列として返します。つまり、time("...")
はstrftime("...", time(0.0))
と同じ結果を返します。しかし、strftime()
を使う場合は2つ目の引数に適当な演算を行うことができますので、9時間の時差に対応する秒数9*3600
を2つ目の引数に足してやれば、日本の時刻に対応した文字列を得ることができます。
実際に、以下の例を試してみましょう。
print "GMT: ", time("%Y/%m/%d %H:%M:%S")
print "JST: ", strftime("%Y/%m/%d %H:%M:%S", time(0)+9*3600)
plot x #ウィンドウ表示用
すると、以下のように、strftime()
を使った方は確かにtime()
関数の場合より9時間進んでおり、キチンと日本の時刻を表示していることが分かります。
GMT: 2015/01/31 13:22:05
JST: 2015/01/31 22:22:05
時刻情報が取得できれば、グラフのラベルや、ファイル名などに用いることができます。
例えば、以下のようなスクリプトで、グラフのタイトルに、現在時刻を表示できます。
set title strftime("Plotted at %Y/%m/%d %H:%M:%S", time(0)+9*3600)
plot sin(x)
また、以下のようにすると、日付や時刻に応じた出力ファイルを生成できます。
set term post
set out strftime("data_%Y%m%d.eps", time(0)+9*3600)
plot sin(x)
set term pop
set out
これを実行すると、日付に応じて例えばdata_20140920.eps
のような名前のファイルを生成することができます。
以下のようなスクリプトを実行すると、時計を作ることができます。
if (exist("loop") == 0){
set angles degrees
set border 0
unset xtics
unset ytics
set size ratio -1
set xrange [-1:1]
set yrange [-1:1]
aconv(deg) = -deg + 90 # 角度を12時位置からの角度に変換する
Lh = 0.4 # 短針の長さ
Lm = 0.9 # 長針の長さ
Ls = 0.95 # 秒針の長さ
od = 1 # 時計の外半径
id = 0.8 # 時計の内半径
set for [i=1:12] arrow i from first id*cos(i*30),id*sin(i*30) to first od*cos(i*30),od*sin(i*30) lw 2 nohead
set style fill solid border rgb "black"
set object 1 circle at 0,0 size od fc rgb "yellow" fs solid lw 2
}
time0 = time(0.0)+9*3600
hour = strftime("%H", time0)
min = strftime("%M", time0)
sec = strftime("%S", time0) + ( time0 - floor(time0) )
set arrow 100 from first 0,0 to Ls*cos(aconv(sec*6)),Lm*sin(aconv(sec*6)) lw 3 lc rgb "cyan" nohead
set arrow 101 from first 0,0 to Lh*cos(aconv(hour*30)),Lm*sin(aconv(hour*30)) lw 9 lc rgb "dark-blue" nohead
set arrow 102 from first 0,0 to Lm*cos(aconv(min*6)),Lm*sin(aconv(min*6)) lw 5 lc rgb "blue" nohead
set label 1 at first 0,-0.3 center strftime("%b %d, %Y (%a) %H:%M:%S", time0)
plot 1/0 notitle
pause 0.05
reread
実行すると、以下のような時計が表示され、実際に動いていきます。(マシンパワーを食うだけで実用性はないですが…)
time()
関数で得た秒数の差を取れば、処理時間を計算できます。例えば、以下のようなスクリプトを考えてみましょう。
time0 = time(0.0)
set samples 100
plot sin(x)
print "required time (100 samples) = ", time(0.0)-time0, " sec"
time0 = time(0.0)
set samples 1000
plot sin(x)
print "required time (1000 samples) = ", time(0.0)-time0, " sec"
time0 = time(0.0)
set samples 10000
plot sin(x)
print "required time (10000 samples) = ", time(0.0)-time0, " sec"
time0 = time(0.0)
set samples 100000
plot sin(x)
print "required time (100000 samples) = ", time(0.0)-time0, " sec"
これはset samples
のパラメータが100の時、1000のとき、10000のとき、100000のときのそれぞれのsin(x)
の表示にかかる時間を計測するためのスクリプトです。それぞれの表示前に、時刻をtime0という変数に保存しておき、表示完了後の時刻との差を取ることで、表示に要した時間を計算します。
私のパソコンでの実行結果は以下のようになりました。このように、確かにサンプル数が増えると所要時間が長くなっています。(100サンプルのときの表示時間が長いのは、ターミナルの初期化のせいだと思われます)
required time (100 samples) = 0.0180009603500366 sec
required time (1000 samples) = 0.0160010457038879 sec
required time (10000 samples) = 0.104005992412567 sec
required time (100000 samples) = 0.452026009559631 sec
古いgnuplotには現在の日付や時刻を得るための関数は用意されていません。しかしながら、以下のようにWindowsなどのコマンドを使うことで現在の日付や時刻を得ることができます。
まず、Windowsで現在の日付を文字列として取得するには以下のようにします。
tmpfile="time.plt"
system("echo date = \"%date%\" > ". tmpfile)
load tmpfile
この例では、2行目でecho date = \"%date%\" > time.plt
というバッチコマンドを実行しています。これは、dateというWindowsの環境変数に入っている内容(%date%)とdate = \"
および\"
という文字列を連結して表示(echo
)するという命令なのですが、> time.plt
の部分で本来表示されるべき内容をファイルtime.plt
に保存させています。これによって生成されるファイルtime.plt
の中身は以下のようになっています。
date = "2010/01/20"
最後にこのtime.plt
をload
することでgnuplot内のdateという変数に文字列2010/01/20
が格納されたわけです。
さらに、以下のように部分文字列を取り出す関数substr()
を使うと、年・月・日をそれぞれ取り出すことができます。
year = substr(date, 1,4)
month = substr(date, 6,7)
day = substr(date, 9,10)
なお、このように数字だけの文字列にしてしまえば、文字列を数値のようにも扱えます。例えば以下のようなことが可能です。
tomorrow = day + 1
これまでの内容の応用編として、例えばプロットした内容を日付のついたファイル名のEPSファイルに保存したい場合は以下のようにします。
tmpfile="time.plt"
system("echo date = \"%date%\" > ". tmpfile)
load tmpfile
year = substr(date, 1,4)
month = substr(date, 6,7)
day = substr(date, 9,10)
set title "year:" . year. " month: " . month . " day: " . day
plot sin(x)
set out "plot". year. month . day .".eps"
set term post eps color
replot
set out
set term pop
上の例の青字で示した部分で、文字列連結演算子.
を用いて文字列を連結しています。つまり、今日が2010年12月11日だとしたらplot20101211.eps
という文字列を作っています。それをset out
コマンドに与えて出力ファイル名に設定しています。
これを実行すると、以下のようなEPSファイルができます。
なお、最後のファイル名の設定の部分では、便利な文字列関数で紹介したstrsubst()
関数を定義しておけば以下のようにしてもOKです。
set out "plot" . strsubst(date, "/", "") . ".eps"
同様に、時刻を取得するには以下のようにします。
tmpfile="time.plt"
system("echo time = \"%time%\" > ". tmpfile)
load tmpfile
原理は日付の取得と全く一緒です。
例えば以下のようにすると、グラフのタイトルに現在時刻を挿入できます。
tmpfile="time.plt"
system("echo time = \"%time%\" > ". tmpfile)
load tmpfile
set title time
plot sin(x)
時間・分・秒を分けて取得するには、さらに以下を付け加えます。
hour = substr(time, 1,2)
minute = substr(time, 4,5)
second = substr(time, 7,11)
また、これらの文字列は数値としても扱えるので、例えば以下のように一日が始まってからの秒数を計算することもできます。
sec_from_midnight = hour*3600+minute*60+second