Handle()は、最初の2つの引数の初期値で与えられる座標にハンドルを配置し、引数の初期値を使ってグラフを描きます。その後、そのハンドルは別の位置まで移動できます。初めに指定されたスクリプト(Handle関数の第3引数)は、マウスボタンが押されてハンドルがドラッグされている間、実行されます。2つ目に指定されたスクリプト(Handle関数の第4引数。オプション指定であり、この例では使用していません)は、マウスボタンが放されるたびに実行されます。これらのイベントについては、Mousetrap()の例を参照してください。
// 正規密度
mu = 0;
sigma = 1;
rsqrt2pi = 1 / Sqrt( 2 * Pi() );
win = New Window( "正規密度",
Graph Box(
Frame Size( 500, 300 ),
X Scale( -3, 3 ),
Y Scale( 0, 1 ),
Y Function( Normal Density( (x - mu) / sigma ) / sigma, x );
Handle(
mu,
rsqrt2pi / sigma,
mu = x;
sigma = rsqrt2pi / y;
);
Text( {1, .7}, "平均 ", mu, {1, .65}, "標準偏差 ", sigma );
)
);
JMPの「Samples」フォルダの「Scripts」フォルダにある「demoPlotProb.jsl」を実行すると、ベータ分布、ガンマ分布、Weibull分布、および対数正規分布の密度関数のグラフが表示されます。正規分布の出力を図12.23に示します。動いているところを確認するため、ぜひご自分でスクリプトを実行してみてください。
図12.23 Handle()の正規密度の例
エラーを回避するために、必ず、ハンドルの座標の初期値をこの例の1行目のように設定してください。
正規密度の例にあるように、ハンドルの座標に関数を使う場合は、Handle()への引数を調整する必要があります。調整しないと、ハンドルマーカーがグラフの外へ出てしまう場合があります。
Y Function( a * x ^ b );
Handle( a, b, a = 2 * x, b = y );
マーカーを最初の位置から座標(3,4)の位置までドラッグしたとします。すると、引数aに6、bに4が設定され、グラフはy = 6x4で再描画され、ハンドルは(6,4)の位置、マウスから離れたところに描かれることになってしまいます。これを修正するには、ハンドルへの最初の引数を、たとえば次のように調整します。
Handle( a / 2, b, a = 2 * x; b=y );
より一般的な状況を考えるために、Handle()の引数がa=f(x)、b=g(y)と定義されているとします。f(x)=xおよびg(y)=yの場合は、最初の2つの引数にa、bを指定するだけです。それ以外の場合は、a = f(x)をxについて、b = g(y)をyについて解いて、適切な引数を求める必要があります。
他の関数を使って、Handle()を制限することもできます。以下の例で作成するインタラクティブなグラフは、Round()を使って、指数と切片が整数だけになるようにしています。
a = 3;
b = 2;
win = New Window( "切片とべき乗",
Graph Box(
Frame Size( 200, 200 ),
X Scale( -10, 10 ),
Y Scale( -10, 10 ),
Y Function( Round( b ) + x ^ (Round( a )), x );
Handle(
a,
b,
a = x;
b = y;
);
Text( {a, b}, " 動かしてください" );
Text( {-9, 9}, "y=", Round( b ), " + x^", Round( a ) );
)
);
図12.24 Handle()の切片とべき乗の例
Handle()とFor()をネストして、複雑なグラフを作成することもできます。
a = 5;
b = 5;
win = New Window( "べき乗",
Graph Box(
Frame Size( 200, 200 ),
X Scale( -10, 10 ),
Y Scale( -10, 10 ),
For( i = 0, i < 1.5, i += .2,
Pen Color( 1 + 10 * i );
Text Color( 1 + 10 * i );
Y Function( i * x ^ Round( a ), x );
Handle(
a,
b,
a = x;
b = y;
);
h = 9 - 10 * i;
Text( {-9, h}, b, "*i*x^", Round( a ), ", i=", i );
) ) );
図12.25 入れ子になったFor()とHandle()
また、1つのグラフ内で複数のハンドルを使用できます。
amplitude = 1;
freq = 1;
phase = 0;
win = New Window( "正弦波",
Graph Box(
Frame Size( 500, 300 ),
X Scale( -5, 5 ),
Y Scale( -5, 5 ),
Y Function( amplitude * Sine( x / freq + phase ), x );
Handle( // 最初のハンドル
freq,
amplitude,
freq = x;
amplitude = y;
);
Handle( phase, .5, phase = x ); // 2つ目のハンドル
Text(
{3, 4},
"振幅: ",
Round( amplitude, 4 ),
{3, 3.5},
"周波数: ",
Round( freq, 4 ),
{3, 3},
"位相: ",
Round( phase, 4 )
);
)
);
図12.26 2つのハンドル