値の大小を色で表す

[戻る]

二つの変数を変化させた時の計算結果の数値を俯瞰したいときがあります. 通常は gnuplot 使って 3 次元グラフで表示しますが, 形状が複雑だと 何がなんだか分からなくなります. そういうとき便利なのが pm3d です. gnuplot にて

set pm3d map set pm3d corners2color c2
としてから splot すると値の大小が色で表された画像が得られます.

余談ですが, この際データは一つ分余分に作っておく必要があります. 例えば x, y ともに 0〜9 を 1 ずつ変化させた時のデータを作りたいのなら

for (x=0;x<=10;x++){
 for (y=0;y<=10;y++){
  if (x==10 || y==10)
   z=MAX; // MIN でもいい
  else
   z=f(x,y);// 計算
  fprintf(fp, "%d %d %lf\n", x,y,z);
 }
 fprintf(fp, "\n");
}
とかいったプログラムにします (これは色が正確に各座標の数値を表したいときの 方法です. 正確でなくていいから滑らかな方がいいのであれば, corners2color の指定値を変えて対処します).

さて, こういった画像をプログラムを通して自分で作りたい時があります. その際問題なのは値から色にどうやって変化させればいいかということです. 調べてみたのですが分からず, 自分でもいろいろやってみたのですが どうも美しくなりません. 結局以下のような gnuplot の標準の色使いを真似ることにしました.

この画像を bmp で保存し RGB の値でプロットしてみたのが下の図です.

赤は 1/2 次, 青は 2 次, 緑は 3 次で変化していってることが分かります. この変化をそのまま表現したのが下のコードです (x に 0〜1 の数値を入れて呼び出せば rgb に値が入ります).

void toRGB(int *r, int *g, int *b, double x){
 if (x>1)
  *r = *b = *g = 255;
 else if (x<0)
  *r = *b = *g = 0;
 else {
  if (x>0.5)
   *b=0;
  else
   *b=(int)(-2044*x*(2*x-1));

  *g = (int)(x*x*x*255.5);
  *r = (int)(sqrt(x)*255.5);
 }
}

2012.4