Color Tables

Direct Graphics でのカラーテーブルの利用

カラーテーブルの作成・編集

IDL 8.2.1 から使えるようになった colortable 関数で簡単にカラーテーブルを作成できる。色は 3 x N の配列で与える。中間色はRGBそれぞれの線形補間で作成されるので、色相が大きく異なる色を用いると中間色がくすんだ色になってしまう。中間色にやや鮮やかな色を指定してやると見栄えがよくなる。

  1. ; Graphics Function で使う場合
  2. ctable = colortable([[255, 0, 0], [255, 255, 255], [0, 0, 255]], ncolors = 256)
  3. p = contour(/test, /fill, rgb_table = ctable

xpalette でインタラクティブにカラーテーブルの編集を行うことができる。

hsl, hsv, pseudo 等を用いてカラーテーブルを作成すると、中間色の彩度が落ち込まない。

カラーテーブルのコントラストとガンマを変更する。デフォルトは min = 0, max = 255, gamma 1.0。引数なしでstretchを実行すると元に戻る。

  1. stretch, min, max, gamma

一部のカラーテーブルは、色番号0と255をそれぞれ背景色(!p.background)と描画色(!p.color)で使うために、黒や白の値を入れている。そうでないカラーテーブルを、Direct Graphics の 8 bit カラーモード(device, decomposed = 0)で利用する時には、以下のようにカラーテーブルを変更して、背景色と描画色用の色を確保しておく必要がある。

  1. device, decomposed = 0
  2. loadct, 74
  3. data = dist(500)
  4. levels = findgen(30) * (max(data) - min(data)) / 29 + min(data)
  5. contour, data, levels = levels, /fill ; 背景、文字、目盛が変な色で表示されてしまう
  6. tvlct, v, /get ; カラーテーブルを取得
  7. v[0, *] = 0 ; 色 #0 を黒にする
  8. v[255, *] = 255 ; 色 #255 を白にする
  9. tvlct, v ; カラーテーブルを設定
  10. !p.color = 0
  11. !p.background = 255
  12. contour, data, levels = levels, c_colors = indgen(30) * 253 / 29 + 1, /fill ; 色番号0と255をcontourで使わないよう、C_COLORS を指定する

modifyct ユーザーが独自に作成したカラーテーブルを保存することができる。modifyctはデフォルトではIDLのインストールディレクトリ以下の resource/colors/colors1.tbl を直接書き換えるので、別の場所にコピーしてそこに書き込むとよい。

  1. $ cp <IDLのインストールディレクトリ>/resource/colors/colors1.tbl mycolor.tbl
  2. ; 現在のカラーテーブルを取得
  3. IDL> tvlct, r, g, b, /get
  4. ; カラーテーブルをファイルに書き込む (41番)
  5. IDL> modifyct, 41, 'My color table', r, g, b, file = 'mycolor.tbl'
  6. ; カラーテーブルをファイルから読み込む
  7. IDL> loadct, 41, file = 'mycolor.tbl'
  8. IDL> xloadct, file = 'mycolor.tbl'

modifyctではカラーテーブルファイルを新規作成できないので、ファイルを新規作成するには次のようにする(全インデックス黒のテーブルを1つ含むファイルが生成される)。一旦ファイルを作成した後は、modifyctで新たなテーブルを追加していくことができる。

  1. openw, lun, 'newfile.tbl', /get_lun
  2. writeu, lun, [1b, bytarr(768), replicate(32b, 32)]
  3. free_lun, lun

カラーテーブルファイルの構造は次のようになっている。デフォルトの colors1.tbl では N = 75。

ファイルヘッダー

オフセット サイズ 説明
0x0000 1 byte カラーテーブルの数 N

カラーテーブル定義ブロック(開始: 0x0001)

オフセット サイズ 説明
0x0001 768 bytes テーブル1のRGBデータ
- 赤成分 256 bytes (0x0001 - 0x0100)
- 緑成分 256 bytes (0x0101 - 0x0200)
- 青成分 256 bytes (0x0201 - 0x0300)
0x0301 768 bytes テーブル2のRGBデータ
...
合計: 768 * N bytes

カラーテーブル名ブロック(開始: 0x0001 + 768*N)

オフセット サイズ 説明
+0x0000 32 bytes テーブル1の名前(スペースでパディングした固定長文字列)
+0x0020 32 bytes テーブル2の名前
...
合計: 32 * N bytes

Python の matplotlib のカラーマップを IDL で使う

matplotlibではさまざまなカラーマップが組み込まれている。Choosing Colormaps in Matplotlibでその一覧を見ることができる。

IDLでmatplotlib組み込みのカラーマップを利用するには、まず、次のようなPythonプログラムを用いて、matplotlib のカラーマップをファイルに保存する。numpy と matplotlib モジュールが使える状態になっている必要がある。

  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. def save_colormap(cmap_name, filename=None, num_colors=256):
  4. procedure_name = f"set_{cmap_name.lower()}"
  5. if filename is None:
  6. filename = f"{procedure_name}.pro"
  7. cmap = plt.get_cmap(cmap_name)
  8. colors = cmap(np.linspace(0, 1, num_colors))
  9. colors_scaled = (colors[:, :3] * 255).astype(int)
  10. idl_code = [
  11. "cmap = [[{}], $".format(", ".join(map(str, colors_scaled[:, 0]))),
  12. " [{}], $".format(", ".join(map(str, colors_scaled[:, 1]))),
  13. " [{}]]".format(", ".join(map(str, colors_scaled[:, 2]))),
  14. "",
  15. ]
  16. with open(filename, 'w') as f:
  17. f.write("\n".join(idl_code))
  18. # 使用例
  19. save_colormap('viridis')

生成されたファイル (上記の例では set_virdis.pro) をIDLで実行すると変数 cmap にカラーテーブルの値が入るので、それを適用する。

  1. ; IDL
  2. ; cmap にカラーテーブルの値が入る
  3. @set_virdis
  4. ; Direct Graphics で利用する場合
  5. tvlct, cmap
  6. ; Graphics Function で利用する場合
  7. p = contour(/test, /fill, rgb_table = cmap)

Python Bridge を利用可能な場合は、matplotlib のカラーマップを直接 IDL で使うこともできる。

  1. ; IDL
  2. np = Python.Import('numpy')
  3. cm = Python.Import('matplotlib.cm')
  4. ; YlOrBrを使う例
  5. cmap = transpose((cm.YlOrBr(indgen(256), bytes=1))[0:2, *])
  6. ; viridis 等の色数固定のカラーマップ (ListedColormap) の場合は次のようにすることもできる
  7. cmap = transpose(byte(np.array(cm.viridis.colors) * 255))
  8. ; Direct Graphics で利用する場合
  9. tvlct, cmap
  10. ; Graphics Function で利用する場合
  11. p = contour(/test, /fill, rgb_table = cmap)

IDL のカラーテーブルを Python の matplotlib で使う

matplotlib で IDL のデフォルトカラーテーブルを利用するには、IDLのインストールディレクトリ以下の resource/colors/colors1.tbl にあるカラーテーブルを直接読むのがてっとり早い。

  1. import os
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. from matplotlib.colors import ListedColormap
  5. # テーブル番号 (0--74)
  6. table = 8
  7. # テーブルファイル名
  8. tblfile = 'IDLのインストールディレクトリ/resource/colors/colors1.tbl'
  9. with open(tblfile, 'br') as f:
  10. f.seek(table * 768 + 1, os.SEEK_SET)
  11. b = f.read(768)
  12. colors = np.frombuffer(b, dtype=np.uint8).reshape(3, 256).T / 255.
  13. cmap = ListedColormap(colors)
  14. gradient = np.linspace(0, 1, 256)
  15. gradient = np.vstack((gradient, gradient))
  16. plt.figure(figsize=(8, 8))
  17. plt.imshow(gradient, aspect='auto', cmap=cmap)
  18. plt.show()
西田圭佑 (NISHIDA Keisuke)
nishida at kwasan.kyoto-u.ac.jp