見出し画像

高校数学10分プログラミング(数学Ⅰ編 3.データの分析)7日目「データの箱ひげ図を描く」

マガジンリスト > 数学Ⅰ編 3.データの分析 > 7日目 課題

おはようございます。

本日は、高校数学10分プログラミング(数学I編 3.データの分析)の7日目です。

本日の課題は、データの箱ひげ図を描くプログラムを作成することです。

箱ひげ図

データの最小値、第1四分位数、中央値、第3四分位数、最大値を、箱と線(ひげ)で表現する図。

図1 箱ひげ図の例


課題

以下の「小テストの点数」のデータの四分位数を求め、その結果を用いて箱ひげ図をキャンバス上に描くプログラムを作成してください。

$$
3 \ 4 \ 9 \ 7 \ 6 \ 10 \ 5 \ 5 \ 7 \ 9 \ 6 \ 8 \ 1 \ 5 \ 7 \ 10 \ 8 \ 6 \ 3 \ 7
$$


ヒント

箱ひげ図を描くために必要となる四分位数については昨日の課題『高校数学10分プログラミング(数学Ⅰ編 3.データの分析)6日目「データの四分位数を求める」』で求めていますので、この結果を利用して箱ひげ図を描いていきます。
箱ひげ図を描く際の各種パラメータは以下の図2のように設定します。

図2 箱ひげ図を描くプログラムで利用する変数

四分位数が分かれば、箱ひげ図は線分を描く関数 line や 四角形を描く関数 rect を利用して比較的簡単に描くことができると思いますが、関数に与えるパラメータの設定がやや複雑です。そのため、今回は以下のデータの箱ひげ図を描くプログラム(完成版)を先に示しておきます。このプログラムを実行してみて、箱ひげ図が正しく描かれていることを確認してください。

// 箱ひげ図を描く
void setup(){
  size(500, 300); // キャンバスの大きさを指定する
  background(255,255,255); // 背景を白色にする
  noFill(); // 図形の塗りつぶしなし
  noLoop(); // 繰り返し処理をしない
  
  // データ
  int data_max_value = 10;
  int data_num = 20; // データ数
  float[] data = {3,4,9,7,6,10,5,5,7,9,6,8,1,5,7,10,8,6,3,7}; // データ

  // 四分位数
  float[] quartile = calcquartile(data_num, data);
//  println(quartile);
  
  // 余白
  float margin = 50.0;
  
  // 表示範囲
  float range = width - 2.0 * margin;
  // 目盛り間の幅
  float segment = range / data_max_value;
  // 目盛りのサイズ
  float segment_size = 10.0;
  
  // 箱ひげ図の両端の線分のサイズ
  float edge_size = 50.0;
  // 箱ひげ図の箱のサイズ
  float box_size = 100.0;
  // 箱ひげ図の中心軸の位置
  float center_line = (height - 2.0 * margin) /2.0;

  translate(margin, margin); // 座標系の原点を移動

  // 軸を描く
  line(0.0, 0.0, range, 0.0);
  // 横軸に目盛りを描く
  fill(0,0,0); // 文字の色を黒色にする
  textSize(20); // 文字のサイズを調整
  textAlign(CENTER, BOTTOM);
  for(int k=0; k<=data_max_value; k++){
    line(segment * k, -segment_size/2.0, segment * k, segment_size/2.0);
    text(k, segment * k, -segment_size/2.0);
  }  
  
  // 箱ひげ図を描く
  noFill();
  // 最小値の線分
  line(segment * quartile[0], center_line - edge_size/2.0, segment * quartile[0], center_line + edge_size/2.0); 
  // 最小値から第1四分位数までの線分
  line(segment * quartile[0], center_line, segment * quartile[1], center_line);
  // 第1四分位数から第2四分位数までの箱
  rect(segment * quartile[1], center_line - box_size/2.0, segment * (quartile[2]-quartile[1]),box_size); 
  // 第2四分位数から第3四分位数までの箱
  rect(segment * quartile[2], center_line - box_size/2.0, segment * (quartile[3]-quartile[2]),box_size);   
  // 第3四分位数から最大値までの線分
  line(segment * quartile[3], center_line, segment * quartile[4], center_line);  
  // 最大値の線分
  line(segment * quartile[4], center_line - edge_size/2.0, segment * quartile[4], center_line + edge_size/2.0); 

}

// バブルソート(昇順)
float[] bubblesort(
  int data_num, // データ数
  float[] data // データの配列
){
  float[] bs = new float[data_num];
  for(int i=0; i<data_num; i++){
    bs[i] = data[i];
  }
  for(int i=0; i<data_num; i++){
    for(int j=1; j<data_num-i; j++){
      if(bs[j-1] > bs[j]){
        float temp = bs[j];
        bs[j] = bs[j-1];
        bs[j-1] = temp;
      }
    }
  }
  return bs;
}

// 四分位数を求める関数
float[] calcquartile(
  int data_num, // データ数
  float[] data // データの配列
){
  // データを昇順にソートする
  float[] bs = new float[data_num];
  bs = bubblesort(data_num, data);

  // 最小値、第1四分位数、第2四分位数、第3四分位数、最大値の順で格納される配列
  float[] Q = {0,0,0,0,0};
  
  // 最小値
  Q[0] = bs[0];
  // 最大値
  Q[4] = bs[data_num-1];
  // 第2四分位数
  int half_size = data_num / 2; // データの半分
  if( data_num % 2 == 0 ){ // データ数が偶数のとき
    Q[2] = ( bs[half_size - 1] + bs[half_size] ) / 2.0;
  } else { // データ数が奇数のとき
    Q[2] = bs[half_size];
  }
  // 第1四分位数と第3四分位数
  if( half_size % 2 == 0){ // データの半分の数が偶数のとき
    Q[1] = ( bs[half_size / 2 - 1] + bs[half_size / 2] ) / 2.0;
    Q[3] = ( bs[data_num - half_size / 2 - 1] + bs[data_num - half_size / 2] ) / 2.0;
  } else { // データの半分の数が奇数のとき
    Q[1] = bs[half_size / 2];
    Q[3] = bs[data_num - half_size / 2 - 1];
  }  
  return Q;
}

ソースコード1 データの箱ひげ図を描くプログラム

なお、スケッチ名は「drawBoxandWhiskerPlot」としておいてください。


それでは、よろしくお願いします。

MK's papa

この記事が気に入ったらサポートをしてみませんか?