gnuplotで、矢印ぐるぐる。

昔、実験で、振り子がゆらゆら、とかあったなぁ、とか思い出して探してみた。
3nen/jikken1/j7/s1/とかいうとこにあった。*1

set xrange [-11:11]
set yrange [-11:11]
set size 0.75, 1
set nokey
plot 0 0
set arrow 1 from 0,0.000000 to 0.993896,9.749470
replot
set arrow 1 from 0,0.198669 to 0.993960,9.948133
replot
set arrow 1 from 0,0.389418 to 0.993620,10.138917
replot
set arrow 1 from 0,0.564642 to 0.992109,10.314295
replot
set arrow 1 from 0,0.717356 to 0.988727,10.467352
replot
・
・
・

こんなのが残ってたので、これを参考にして、矢印ぐるぐるを作ってみた。

#! /usr/bin/perl
use strict;
use warnings;

my $datafile = shift @ARGV or die "usage: $0 data_filename [sleep_time]\n";
my $sleep_time = shift @ARGV || 0;

open DATA, "< $datafile" or die "can't open $datafile\n";
open GNUPLOT, "| gnuplot" or die "can't open gnuplot\n";
select( ( select(GNUPLOT), ( $| = 1 ) )[0] );

print GNUPLOT
    "set xrange [-1.5e11:1.5e11]\n",
    "set yrange [-1.5e11:1.5e11]\n",
    "set size 0.75, 1\n",
    "set nokey\n",
    "plot 0 0\n";

while( <DATA> ){
    next if /^#/;
    my( $x, $y ) = /^([\d.e+-]*)\t([\d.e+-]*)$/ or die;
    printf GNUPLOT "set arrow 1 from 0,0 to %g,%g\nreplot\n", $x, $y;
    sleep $sleep_time;
}

矢印がぐるぐるするかどうかは、データファイル次第だけど。


記憶だけをたよりに、select(select(…を書いたら、

select( ( select(GNUPLOT), ( $| = 1 ) )[1] );

とかなってた。エラーがでなくて気づかず。

select( ( select(GNUPLOT), ( $| = 1 ) )[0] );

が正解。

ついでにメモ。
selectは引数のファイルハンドルを、標準の出力先にする。で、それまでの標準のファイルハンドルを返す。
"$| = 1;"は、その時点での標準の出力先のバッファリングをオフにする。*2
それで、( 'それまでの出力先', 1 )というリストの[0]を取り出して、selectに渡すので、標準の出力先は元に戻る、と。

単純に、

select GNUPLOT;
$| = 1;

でもよかったかな。

*1:s1って何だっけ?

*2:出力すると、バッファリングされずに、すぐに出力される。