検索可能な散布図
2つのデータについての散布図を描くことがよくあります。
表計算ソフトでも,Rでもできます。
では,その散布図で,特徴的な点があったときに,その点についての情報を引き出すには?
たとえば,数学と英語の試験の得点について散布図を描きます。
すると,「数学は得意だが英語が苦手」というような点(人)がいることがすぐわかるでしょう。
では,それは誰で,他の科目の得点はどうなっているでしょうか。
表計算ソフトでは,一覧表で並べ替えをしておき,目視で探すくらいでしょう。
しかし,Cindyscriptを使えば,散布図上の点をクリックするだけで該当するデータを表示することができます。
データは,前節「成績処理」と同じものを使います。「成績処理」のページにあるサンプルファイルをダウンロードして使いましょう。
(1) 散布図を描く
4回の試験のうち2つを選びます。それを test1,test2 としましょう。
test1=1;
test2=2;
test1の得点をx座標,test2の得点をy座標としてリストを作ります。
datalist2 が行インデックスを削除したリストなので,このリストの各要素に対して,(test1+1)番目と(test2+1)番目の要素を座標の形にしてリストにします。(1番目は学籍番号)
散布図での点になるので,ptとしました。
100点満点なので10で割っておきます。
この点のリスト pt をPointdata() で一括して点として表します。
pt=apply(datalist2,[#_(test1+2)/10,#_(test2+2)/10]);
Pointdata("1",pt);
#_(test1+2)/10 としているのは,学籍番号と氏名の列があるので test1+2 になるわけです。念のため。
横軸,縦軸,項目名を描いておきましょう。
Listplot("1",[[10.5,0],[0,0],[0,10.5]]);
Letter([[11,0],"e",rowindex_(test1+2),[0,11],"c",rowindex_(test2+2)]);
次に目盛を打ちますが,横軸は0から,縦軸は1からとします。
forall(0..10,drawtext([#-0.2,-0.4],#*10));
forall(1..10,drawtext([-0.7,#-0.1],#*10));
ここで,forall(リスト,処理) はリストの各要素に対して処理を行う関数です。
0..10 で0から10までの整数のリストができ,それぞれについて座標を計算して表示します。
座標の値の -0.2 や -0.4 は結果を見て調整します。全体のスケールによって変えます。
drawtext();はCindyscriptの関数で,TeXには書き出されません。
TeXに書き出す目盛はこれとは別にHtickmark()とVtickmark()で描きます。
Addax(0);
forall(0..10,Htickmark([#,"s",text(#)]));
forall(1..10,Vtickmark([#,"w",text(#)]));
また,TeXに書き出した点は小さいので,Ptsize() で少し大きくしておきます。
Ptsize(4);
を Pointdata("1",pt); の前に描いておきます。
ただし,これら,Htickmark(),Vtickmark()で描いた目盛や点の大きさはCinderellaの描画面には反映されません。
次の図がTeXに書き出した図です。
これで表示ができました。test1とtest2を変えれば,他の組み合わせで瞬時に散布図が変わります。
(2) 散布図から該当者を検索する
散布図は2項目間の相関を見るときによく使われます。表計算ソフトでできるのはここまでですが(相関係数の計算などはもちろんできます)Cindyscriptを使えば,散布図上の点をクリックして,該当者の情報(学籍番号,得点)を表示することができます。
たとえば,上の図で,第1回がおよそ70点の者が何人かいますが,上の学生は第2回が100点,下の学生は第2回が約40点です。これはだれでしょうか。点をクリックすると表示するようにします。
原理は簡単で,クリックした位置から得点を逆算し,select()で抽出するのです。
クリックした位置からの範囲は少し余裕を持たせましょう。
マウスボタンをクリックしたときの位置は,Mouse Clickスロットに,関数 mouse() を書くことで得られます。
mp=mouse();
とすると,mp.x でx座標,mp.y でy座標が取得できます。
今は得点の10分の1を座標にしていますので,座標を10倍すれば得点になります。
mp=mouse();
xa=(mp.x-0.2)*10;
xb=(mp.x+0.2)*10;
ya=(mp.y-0.2)*10;
yb=(mp.y+0.2)*10;
横軸でxaからxbまで,縦軸でyaからybまでの範囲とします。
0.2 はクリックした位置からの範囲です。大きな値にすれば範囲が広がります。
こうして取得した範囲 xa,xb,ya,yb を用いて datalist2かr該当する要素を抽出するスクリプトをDrawスロットの続きに書きます。
plist=select(datalist2,xa<=#_(test1+2) & #_(test1+2)<=xb & ya<=#_(test2+2) & #_(test2+2)<=yb);
plist には何件かのデータが入っているでしょう。これをdrawtext(位置,文字,option) で描画面に表示します。
y=2;
repeat(length(plist),s,
drawtext([12,y+s],plist_s,size->18);
);
次の図は,第1回が38点,第2回が49点である点の付近をクリックした結果です。
学籍番号と,該当する得点だけでよければ,drawtext([12,y+s],plist_s,size->20); のかわりに
drawtext([12,y+s],plist_s_1+":"+plist_s_(test1+2)+","+plist_s_(test2+2),size->20);
とします。