箱ひげ図

四分位数を求めて箱ひげ図を描きます。

四分位数の求め方はいくつかあるようです。

高等学校の数学の教科書では、簡便な方法を用いていますが、ここでは、床関数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には次のように出力されます。

< 戻る >