Processing(データの取り込み2)

Processingのデータ取り込みまとめの続きです。

Tableから最大値と最小値を取り出す

最大値と最小値を取り出すプログラム

範囲を変換するときに最大値と最小値は数値を直接入力していました。このプログラムでは行数の時と同じように、あらかじめ各列の最大値最小値を調べる必要があります。
しかし、ProcessingにはTableの最大値と最小値を調べるメソッドは準備されていません。

そこで、最大値と最小値を求めるプログラムを書いてみます。

  • 最大値
Table dataArray;
void setup()
{
    dataArray = loadTable("stars.csv", "header"); 
}
void draw()
{
    float resultValue = dataArray.getFloat(0, 0);
    for (int i = 1; i < dataArray.getRowCount(); i++)
    {
        if (resultValue < dataArray.getFloat(i, 0))
        {
            resultValue = dataArray.getFloat(i, 0);
        }
    }
    println(resultValue);
    noLoop();   
}

出力:2220.12

  • 最小値
Table dataArray;
void setup()
{
    dataArray = loadTable("stars.csv", "header"); 
}
void draw()
{
    float resultValue = dataArray.getFloat(0, 0);
    for (int i = 1; i < dataArray.getRowCount(); i++)
    {
        if (resultValue > dataArray.getFloat(i, 0))
        {
            resultValue = dataArray.getFloat(i, 0);
        }
    }
    println(resultValue);
    noLoop();
}

出力:-3678.19

最小値と最大値を求めるプログラムの違いはif文の条件だけですが、注意点がいくつかあります。

結果を格納する変数には最初の値を入れておく

例えば最大値を求めるプログラムでfloat resultValue = 0;としてしまうと、最大値が0よりも小さい場合に結果が0となってしまいます。
同様に最小値を求めるプログラムでも、大きな数字を設定したとしても、それよりも大きな数字が最小値の場合は最初に設定した値が最小値になってしまいます。

それぞれ変数に格納できる最大・最小値を設定すれば対応は可能ですが、言語によって変数に割り当てられているbit数が異なっていたり、同じ言語でもこれから絶対にbit数が変わらないということも保証できないので、あまりいい方法ではありません。

それなので、はじめに比較対象の最初の値を入れておくことで解決します。

for文は1から始める

for文ではint i = 0;と書く場合が多いかと思いますが、今回はint i = 1;としています。これは、変数の初期値にi=0の時の値をあらかじめセットしているからです。 0から始めてもプログラムは動きますし、実行時間もほとんど変わりませんが、for文の中で最初の1回だけ、無駄な動きをしていることになります。

プログラムを関数にする

このままプログラムに組み込むと、列の回数だけ繰り返す必要があります。今回のデータでは、X、Y、sizeの3つがあるのでそれぞれ3回ずつとなるので、長くわてかりづらくなります。

そこで、それぞれ関数にまとめることで使いまわししやすいようになります。

関数は下記のような構造で、setupやdrawの外側に書きます。

関数が返す値のデータ型 関数の名前(関数が受け取るデータ型と変数名)
{
関数が行う処理
戻す値
}
int FunctionName(int receivedData)
{
        int value = 0;
        //process
        return value;
}

ここに最大値や最小値を求めるプログラムを当てはめていきます。

  • 最大値を求める関数GetTableMaxValue
float GetTableMaxValue(Table targetTable, int targetColm)
{
    float resultValue = targetTable.getFloat(0, targetColm);
    for (int i = 0; i < targetTable.getRowCount(); i++)
    {
        if (resultValue > targetTable.getFloat(i, targetColm))
        {
            resultValue = targetTable.getFloat(i, targetColm);
        }
    }
    return resultValue;
}
  • 最小値を求める関数GetTableMinValue
float GetTableMinValue(Table targetTable, int targetColm)
{
    float resultValue = targetTable.getFloat(0, targetColm);
    for (int i = 0; i < targetTable.getRowCount(); i++)
    {
        if (resultValue < targetTable.getFloat(i, targetColm))
        {
            resultValue = targetTable.getFloat(i, targetColm);
        }
    }
    return resultValue;
}

それぞれの関数に調べたいTable型の変数と、調べたい列の番号を渡すと、調べた結果が戻ってきます。

実際に使う場合は、変数に値を代入する形で書きます。

Table dataArray;
float maxX, minX;
float maxY, minY;
void setup()
{
    dataArray = loadTable("stars.csv", "header"); 
    maxX = GetTableMaxValue(dataArray, 0);  
    minX = GetTableMinValue(dataArray, 0);
    maxY = GetTableMaxValue(dataArray, 1);  
    minY = GetTableMinValue(dataArray, 1);
    
    size(1920, 1080);
    background(255, 255, 255);
}
void draw()
{
}

float GetTableMinValue(Table targetTable, int targetColm)
{
    float resultValue = targetTable.getFloat(0, targetColm);
    for (int i = 0; i < targetTable.getRowCount(); i++)
    {
        if (resultValue < targetTable.getFloat(i, targetColm))
        {
            resultValue = targetTable.getFloat(i, targetColm);
        }
    }
    return resultValue;
}

float GetTableMaxValue(Table targetTable, int targetColm)
{
    float resultValue = targetTable.getFloat(0, targetColm);
    for (int i = 0; i < targetTable.getRowCount(); i++)
    {
        if (resultValue > targetTable.getFloat(i, targetColm))
        {
            resultValue = targetTable.getFloat(i, targetColm);
        }
    }
    return resultValue;
}

あとは今まで作ったプログラムで最大値・最小値を数値で書いていた部分を変数に置き換えます。

Table dataArray;
float maxX, minX;
float maxY, minY;
float maxSize, minSize;
void setup()
{
    dataArray = loadTable("stars.csv", "header"); 
    maxX = GetTableMaxValue(dataArray, 0);  
    minX = GetTableMinValue(dataArray, 0);
    maxY = GetTableMaxValue(dataArray, 1); 
    minY = GetTableMinValue(dataArray, 1);
    maxSize = GetTableMaxValue(dataArray, 2);
    minSize = GetTableMinValue(dataArray, 2);
    
    size(1920, 1080);
    background(255, 255, 255);
}
void draw()
{
    for (int i = 0; i < dataArray.getRowCount(); i++)
    {
        float coordX = map(dataArray.getInt(i,0), maxX, minX, 0, width);
        float coordY = map(dataArray.getInt(i,1), maxY, minY, 0, height);
        float size = map(dataArray.getInt(i,2), maxSize, minSize, 1, 5) ;
        
        ellipse(coordX, coordY, size, size);
    }
    save("stars.jpg");
}


float GetTableMinValue(Table targetTable, int targetColm)
{
    float resultValue = targetTable.getFloat(0, targetColm);
    for (int i = 0; i < targetTable.getRowCount(); i++)
    {
        if (resultValue < targetTable.getFloat(i, targetColm))
        {
            resultValue = targetTable.getFloat(i, targetColm);
        }
    }
    return resultValue;
}

float GetTableMaxValue(Table targetTable, int targetColm)
{
    float resultValue = targetTable.getFloat(0, targetColm);
    for (int i = 0; i < targetTable.getRowCount(); i++)
    {
        if (resultValue > targetTable.getFloat(i, targetColm))
        {
            resultValue = targetTable.getFloat(i, targetColm);
        }
    }
    return resultValue;
}

データ取り込みの基本的な部分はこれくらいかと思います。勉強していくうえで必要だと感じたものは、またまとめてみようと思います。

このプログラムを書き換えて、表示する範囲を変えたり、描画する図形を変えたり、描画色を変えたり、いろいろと応用することができます。

f:id:ArtificialArts:20180526103112j:plain