度数分布とヒストグラム
データの度数分布を作成し、ヒストグラムを書きます。
度数分布の階級は、階級の数や「以上・未満」と「より大・以下」を指定できるようにします。
データは表計算ソフトなどで入力し、CSVファイルにして、コピーします。
もちろんそのまま手入力してもかまいません。
まず、度数分布を作成し、グラフを描く関数を定義します。
Initializationスロットに書きます。
=========================================
// 度数分布表とヒストグラムを描く
// 縦軸目盛は15段階、度数の最大値から自動計算
// Rangeleft,Rangeright, 階級の下限と上限
// Classno 階級数
hist(rightflag,li,col):=(
lineflag=li; // KETCindyのために変数に代入しておく
hlen=length(Datalist); // データ数
hrange=Rangeright-Rangeleft;
//階級の区切り値を設定
hbreaks=apply(1..(Classno+1),Rangeleft+(#-1)*hrange/Classno);
//度数分布 hfreq を作る
// 各階級の上の値以上のものを数えて、残り個数から引く。
// 階級の下限以上、上限未満のものが数えられる。
// rightflag==1 のときは より大・以下 とする
hfreq=[]; // 度数データ 範囲,度数
hnokori=hlen;
hmax=0; // 度数の最大値
repeat(Classno,t,
if(rightflag==0,
hdosu=length(select(Datalist,#>=hbreaks_(t+1)));
hhist=hnokori-hdosu;
hfreq=append(hfreq,[text(hbreaks_t)+"以上"+text(hbreaks_(t+1))+"未満",hhist]),
hdosu=length(select(Datalist,#>hbreaks_(t+1)));
hhist=hnokori-hdosu;
hfreq=append(hfreq,[text(hbreaks_t)+"より大"+text(hbreaks_(t+1))+"以下",hhist]);
);
hnokori=hdosu;
if(hhist>hmax,hmax=hhist);
);
// 度数分布表
drawtable([-7,1],hfreq,border->false);
// ヒストグラム
// 軸
draw([0,0],[21,0]);
draw([0,0],[0,16]);
// 目盛
repeat(15, draw([-0.1,#],[0.1,#]));
if(lineflag==1,
repeat(15, draw([0,#],[21,#],dashtype->3));
);
yhaba=ceil(hmax/15);
ymax=ceil(hmax/15)*15; // 縦軸最大値
apply(0..15,drawtext([-1.1,#-0.2],#*yhaba)); // 縦の目盛
hposx=0;
repeat(Classno,
fillpoly([[hposx,0],[hposx+1.9,0],[hposx+1.9,hfreq_#_2/yhaba],[hposx,hfreq_#_2/yhaba]],color->col);
drawtext([hposx-0.2,-0.5],hbreaks_#);
hposx=hposx+2;
);
drawtext([hposx-0.2,-0.5],hbreaks_(Classno+1));
//平均などの表示
haverage=sum(Datalist)/hlen;
sortdata=sort(Datalist);
if(iseven(hlen),
hmedian=(sortdata_(hlen/2)+sortdata_(hlen/2+1))/2,
hmedian=sortdata_(hlen/2+1);
);
drawtext([-7,Classno+4.7],"データ数:"+length(Datalist));
drawtext([-7,Classno+3.7],"最大値 :"+max(Datalist));
drawtext([-7,Classno+2.7],"最小値 :"+min(Datalist));
drawtext([-7,Classno+1.7],"平均値 :"+haverage);
drawtext([-7,Classno+0.7],"中央値 :"+hmedian);
);
===============================================
Drawスロットのページには、データと、関数呼び出しを書きます。
===============================================
// dataにデータのリストを書く
data=[60,75,70,73,52,68,65,71,56,56,56,82,63,66,55,67,73,65,77,75,54,69,67,86,70,58,76,61,64,83,77,61,62,63,68,73,80,67,68,69,75,70,72,52,68,65,71,56,56,56,82,63,66,55,67,73,65,77,75,54,69,67,86,70,81,76,61,64,80,87,61,62,63,68,73,80,67,68,69,75,70,73,52,68,65,71,56,56,56,82,63,66,55,67,73,65,77,75,54,69,67,86,70,81,76,61,64,83,77,61,62,63,68,73,80,67,68,69,75,70,72,52,68,65,71,56,56,56,82,63,66,55,67,73,65,77,75,54,69,67,86,71,81,76,61,64,80,77,61,62,63,68,73,80,67,68,69,75,70,73,52,68,65,71,56,56,56,83,63,66,55,67,73,65,77,75,54,69,67,86,70,81,76,61,64,83,77,67,72,77,61,62,63,68,73,80,67,68,89,75,70,73,52,68,65,71,56,56,56,81,63,66,55,67,73,65,77,75,54,62,63,68,73,80,67,68,69,75,73,73,52,68,65,71,56,56,56,81,63,66,55,67,73,65,77,75,54,69,57,86,70,81,76,61,64,83,77,61,62,63,68,73,80,61,68,89,75,70,72,52,68,65,71,56,56,56,82,63,66,55,67,73,65,77,75,54,69,67,86,71,81,76,61,64,80,77,61,62,63,68,73,80,67,68,69,75,70,73,52,68,65,71,56,56,56,81,63,66,55,67,73,65,77,75,54,69,67,86,70,81,76,61,64,83,77,61,62,63,68,73,80,61,68,69,75,70,72,52,68,65,71,56,56,56,82,63,66,55,67,73,65,77,75,54,69,87,86,71,81,76,61,64,80,77,61,62,63,68,73,80,67,68,69];
Datalist=sort(data);
println("最小値:"+min(Datalist)+" 最大値:"+max(Datalist));
Rangeleft=50; // 階級の下限と上限
Rangeright=90;
Classno=10; // 階級の数
// ヒストグラム作成
// 第1引数は 0 : 以上・未満 1: より大・以下
// 第2引数は 0 : 横のラインを点線で表示しない 1:する
// 第3引数はカラーコード
hist(1,1,[0,0,1]);
================================================
入力するデータは並べ替えてある必要はありません。
実行すると最小値と最大値がコンソールに表示されるので、それを参考に階級の下限と上限、階級の数を再設定します。
次のように画面左側に度数分布、中央にヒストグラムが表示されます。
これをKeTCindyでTeXファイルにします。
そのためのスクリプトをInitilaizationスロットに追加します。
================================================
// KETCindy用ヒストグラム描画 hist()の中の変数を利用している
Scioutput(alp):=(
// 軸
Listplot("1",[[0,0],[21,0]]);
Listplot("2",[[0,0],[0,16]]);
// 目盛
repeat(15,Listplot("M"+text(#),[[-0.1,#],[0.1,#]]));
if(lineflag==1,
repeat(15, Listplot("L"+text(#),[[0,#],[21,#]],["do"]));
);
lt=apply(0..15,[[-1,#],"c",text(#*yhaba)]); // 縦の目盛
Letter(flatten(lt));
hposx=0;
lt=[];
repeat(Classno,
Listplot("Hi"+text(#),[[hposx,0],[hposx+2,0],[hposx+2,hfreq_#_2/yhaba],[hposx,hfreq_#_2/yhaba],[hposx,0]]);
// 柱状グラフの色塗り Listplot()の命名規則が変わったら変更する
Com2nd("Shade(sgHi"+text(#)+","+text(alp)+")");
lt=append(lt,[[hposx,0],"sg2",text(hbreaks_#)]);
hposx=hposx+2;
);
lt=append(lt,[[hposx,0],"sg2",text(hbreaks_(Classno+1))]);
Letter(flatten(lt));
);
============================================
Drawスロットにも追加します。
===========================================
// KETCindy 書き出し if (1==1 にすると書き出される
// 書き出されるのはヒストグラムだけ。左側の数値は書き出されない
// 実行すると、目盛の数字とデータ名がCinderellaの画面上では少しダブって表示される
// KETCindy用では色のかわりに塗る濃さを指定を0〜1で指定する
Ketinit();
Setunitlen("5mm");
Addax(0);
Scioutput(0);
===========================================
書き出されるのはヒストグラムの部分だけです。データ部分は、TeXファイルの方で整形して表示するほうが望ましいでしょう。
「以上・未満」を「より大・以下」にするだけで、同じ階級の区切りでもヒストグラムが変わってくるのはよく知られています。
次の図は、「より大・以下」にした場合です。また、柱にうすく色(モノクロ)を塗っています。
いろいろと条件を変えながら、適切な図を作ればよいでしょう。
< 戻る >