箱ひげ図
四分位数を求めて箱ひげ図を描きます。
四分位数の求め方はいくつかあるようです。
高等学校の数学の教科書では、簡便な方法を用いていますが、ここでは、床関数floor()と天井関数ceil() を用います。
分位数をq、データ数をnとしたとき
t=1-q+q*n
tが整数ならば t 番目
そうでなければ (ceil(t)-t)*[floor(t)番目]+(t-floor(t))*[ceil(t)番目]
とします。
第1四分位数は q=1/4 , 中央値は q=1/2 , 第3四分位数は q=3/4 です。
スクリプトは
sortdata=sort(data);
n=length(sortdata);
t=1-q+q*n;
if(isinteger(t),
qu=sortdata_t,
qu=(ceil(t)-t)*sortdata_floor(t)+(t-floor(t))*sortdata_ceil(t);
);
です。
1行目で、sortdata はデータのリスト data を昇順に並べ替えています。
次のスクリプトが全体の関数の定義です。Initializationスロットに書きます。
============================================
quartile(data,label,no):=(
qrange=Rangeright-Rangeleft;
qscale=20/qrange;
q1=quantile(data,1/4); // 第1四分位数
q2=quantile(data,2/4); // 中央値
q3=quantile(data,3/4); // 第3四分位数
// 箱ひげ図
qx0=(min(data)-Rangeleft)*qscale;
qx1=(q1-Rangeleft)*qscale;
qx2=(q2-Rangeleft)*qscale;
qx3=(q3-Rangeleft)*qscale;
qx4=(max(data)-Rangeleft)*qscale;
qy=(no-1)*3+1;
drawtext([0,qy+2],label,size->16);
fillpoly([[qx1,qy],[qx3,qy],[qx3,qy+2],[qx1,qy+2]],color->[0.97,0.97,0]);
drawpoly([[qx1,qy],[qx3,qy],[qx3,qy+2],[qx1,qy+2]]);
draw([qx2,qy],[qx2,qy+2]);
draw([qx0,qy+1],[qx1,qy+1]);
draw([qx0,qy+0.8],[qx0,qy+1.2]);
draw([qx3,qy+1],[qx4,qy+1]);
draw([qx4,qy+0.8],[qx4,qy+1.2]);
drawtext([-8,(no-1)*5+4.2],label,size->14);
drawtext([-6,(no-1)*5+3.5],"データ数:"+length(data),size->14);
drawtext([-7,(no-1)*5+2.7],"第1四分位数:"+q1,size->14);
drawtext([-7,(no-1)*5+1.5]," 中央値 :"+q2,size->14);
drawtext([-7,(no-1)*5+0.5],"第3四分位数:"+q3,size->14);
);
quantile(data,q):=(
sortdata=sort(data);
n=length(sortdata);
t=1-q+q*n;
if(isinteger(t),
qu=sortdata_t,
qu=(ceil(t)-t)*sortdata_floor(t)+(t-floor(t))*sortdata_ceil(t);
);
);
drawscale():=(
qrange=Rangeright-Rangeleft;
qscale=20/qrange;
apply(0..Memori,drawtext([20*#/Memori-0.3,-0.8],Rangeleft+#*qrange/Memori));
draw([-1,0],[21,0]);
repeat(Memori+1,s,start->0,
draw([20*s/Memori,-0.1],[20*s/Memori,0.1]);
);
);
===============================================
データは複数個扱えます。CindyScriptのDrawスロットのスクリプトに書き込みます。
===============================================
// dataにデータのリストを書く
data1=[38, 54, 47, 46, 36, 42, 39, 37, 53, 46, 40, 36, 45, 36, 53, 40, 51, 46, 45, 42, 48, 53, 58, 49, 48, 50, 41, 57, 51, 42, 47, 44, 47, 38, 53, 44, 49, 45, 46, 46];
data2=[60, 59, 48, 57, 63, 54, 59, 52, 55, 56, 66, 58, 53, 59, 60, 64, 54, 42, 52, 56, 54, 50, 72, 54, 50, 52, 53, 58, 63, 48, 54, 50, 59, 55, 60, 56, 63, 60, 52, 62];
// 表示目盛の下限と上限、目盛の数を設定。
//コンソールにそれぞれのデータの最小値と最大値が表示されるのでそれを参考に
Rangeleft=30;Rangeright=80;
Memori=10;
drawscale();
// 箱ヒゲ図の表示 データリスト、タイトル、番号
quartile(data1,"試料A",1);
quartile(data2,"試料B",2);
===============================================
次のようになります。
提示教材としてはこれででき上がりです。
これをKETCindyで出力するために、次のスクリプトをInitializationスロットに追加します。
==============================================
drawscaleKETCindy():=(
qrange=Rangeright-Rangeleft;
qscale=20/qrange;
Mlist=apply(0..Memori,[[20*#/Memori-0.1,-0.6],"c",text(Rangeleft+#*qrange/Memori)]);
Mlist=flatten(Mlist);
Letter(Mlist);
Listplot("1",[[-1,0],[21,0]]);
repeat(Memori+1,s,start->0,
Listplot(text(s+2),[[20*s/Memori,-0.1],[20*s/Memori,0.1]]);
);
);
quartileKETCindy(data,label,no):=(
qrange=Rangeright-Rangeleft;
qscale=20/qrange;
q1=quantile(data,1/4); // 第1四分位数
q2=quantile(data,2/4); // 中央値
q3=quantile(data,3/4); // 第3四分位数
// 箱ひげ図
qx0=(min(data)-Rangeleft)*qscale;
qx1=(q1-Rangeleft)*qscale;
qx2=(q2-Rangeleft)*qscale;
qx3=(q3-Rangeleft)*qscale;
qx4=(max(data)-Rangeleft)*qscale;
qy=(no-1)*3+1;
Letter([0,qy+2],"c",label);
Listplot("Bx"+text(no),[[qx1,qy],[qx3,qy],[qx3,qy+2],[qx1,qy+2],[qx1,qy]]);
Listplot("HH1"+text(no),[[qx2,qy],[qx2,qy+2]]);
Listplot("HH2"+text(no),[[qx0,qy+1],[qx1,qy+1]]);
Listplot("HH3"+text(no),[[qx0,qy+0.8],[qx0,qy+1.2]]);
Listplot("HH4"+text(no),[[qx3,qy+1],[qx4,qy+1]]);
Listplot("HH5"+text(no),[[qx4,qy+0.8],[qx4,qy+1.2]]);
);
================================================
さらに、Drawスロットのさきほどのスクリプトに追加します。
================================================
Ketinit();
Setunitlen("5mm");
Addax(0);
Fhead="fig";
drawscaleKETCindy();
quartileKETCindy(data1,"試料A",1);
quartileKETCindy(data2,"試料B",2);
===============================================
書き出されるのは箱ヒゲ図だけで、左側の数値は書き出されません。
実行すると、目盛の数字とデータ名がCinderellaの画面上ではダブって表示されますが、出力のときだけなのでよいでしょう。
TeXには次のように出力されます。
< 戻る >